这里基于 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 时,是将将服务提供者的网络地址硬编码在代码中的(即使编写在配置文件中也算)。
如果服务提供者的网络地址发生变化,我们就需要去修改服务消费者的代码,然后重新发布。
为了构建一个良好的微服务系统,我们需要引入服务发现组件,这样服务提供者可以将自己的提供的服务信息注册到服务发现组件中,服务消费者可以通过服务发现组建获取到需要访问的服务信息,然后再去访问相关的服务。