這里基於 Spring Boot 開發一個服務提供者和一個服務消費者。沒有服務發現組件,服務消費者直接通過 URL 來訪問服務提供者對外提供的服務。
- 服務提供者通過 REST 接口對外提供服務。
- 服務消費者通過 RestTemplate 調用服務提供者的 API。
一. 服務提供者代碼
使用 Spring Boot 創建項目 simple-provider-user。
- 使用 Spring Data JPA 作為持久層框架;
- 使用 H2 作為數據庫。
引入依賴:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
准備數據 schema.sql:
drop table user if exists; create table user ( id bigint generated by default as identity, username varchar(40), name varchar(20), age int(3), balance decimal(10,2), primary key (id) ); insert into user (id, username, name, age, balance) values (1, 'account1', '張三', 20, 100.00); insert into user (id, username, name, age, balance) values (2, 'account2', '李四', 28, 180.00); insert into user (id, username, name, age, balance) values (3, 'account3', '王五', 32, 280.00);
實體類 User:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String username; @Column private String name; @Column private Integer age; @Column private BigDecimal balance; // setters getters }
創建 DAO:
@Repository public interface UserRepository extends JpaRepository<User, Long> { }
創建 Controller:
@RestController public class UserController { @Autowired private UserRepository userRepository; @GetMapping("/{id}") public User findById(@PathVariable Long id) { User user = userRepository.findOne(id); return user; } }
編寫配置文件 application.yml:
server: port: 8000 spring: jpa: generate-ddl: false show-sql: true hibernate: ddl-auto: none datasource: platform: h2 logging: level: root: INFO org.hibernate: INFO
測試。訪問 http://localhost:8000/1, 獲得結果:
{ "id": 1, "username": "account1", "name": "張三", "age": 20, "balance": 100 }
二. 服務消費者代碼
使用 Spring Boot 創建一個引來如 web starter 的項目。
添加 RestTemplate Bean :
@SpringBootApplication public class SimpleConsumerMovieApplication { public static void main(String[] args) { SpringApplication.run(SimpleConsumerMovieApplication.class, args); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
通過 RestTemplate 訪問服務提供者的 API:
@RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { String url = "http://localhost:8000/" + id; return restTemplate.getForObject(url, User.class); } }
配置服務消費者啟動端口:
server: port: 8010
測試:
分別啟動服務提供者進程和服務消費者進行。訪問:localhost:8010/user/1,結果如下:
{ "id": 1, "username": "account1", "name": "張三", "age": 20, "balance": 100 }
三. 小結
本示例中只有服務提供者和服務消費者兩個角色,沒有引入服務發現組件,存在一些缺點:
我們在訪問服務提供者 API 時,是將將服務提供者的網絡地址硬編碼在代碼中的(即使編寫在配置文件中也算)。
如果服務提供者的網絡地址發生變化,我們就需要去修改服務消費者的代碼,然后重新發布。
為了構建一個良好的微服務系統,我們需要引入服務發現組件,這樣服務提供者可以將自己的提供的服務信息注冊到服務發現組件中,服務消費者可以通過服務發現組建獲取到需要訪問的服務信息,然后再去訪問相關的服務。