本次分享的是关于springcloud服务注册与发现的内容,将通过分别搭建服务中心,服务注册,服务发现来说明;现在北京这边很多创业公司都开始往springcloud靠了,可能是由于文档和组件比较丰富的原因吧,毕竟是一款目前来说比较完善的微服务架构;本次分享希望能给大家带来好的帮助;
就我现在了解到并且用的比较多的注册中心有zookeeper和Eureka,我的上上篇文章分享了dubbo+zookeeper来构建服务,因此本次用的是Eureka,springcloud框架也是推荐它来作为注册中心,当然可以集成其他的服注册中心,毕竟springcloud依赖于springboot来构建项目的,因此集成其他组件是很快的;首先创建注册中心项目eureka_server,通过如下引入依赖:
1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-eureka-server</artifactId>
4 </dependency>
然后在application.yml文件中增加配置项:
1 server:
2 port: 2001
3 spring:
4 application:
5 name: eureka-server
6 eureka:
7 client:
8 register-with-eureka: false #禁止自己当做服务注册
9 fetch-registry: false #屏蔽注册信息
10 instance:
11 prefer-ip-address: true
12 instance-id: ${spring.application.name}:${server.port}
配置完成后,还需要再启动类增加注解 @EnableEurekaServer ,设置基本完成即可运行,访问 http://localhost:2001/ 得到如下界面:
有了服务注册中心,我们还需要提供一些服务并且把这些服务注册到服务中心去,这里为了方便先创建一个服务提供者和消费者共同使用的接口模块项目eureka_api,并创建如下接口和请求返回参数实体类:
1 public interface UserInterface {
2
3 @PostMapping("/users")
4 MoRp<List<MoUser>> getUsers(MoRq rq);
5
6 @GetMapping("/msg")
7 String getMsg();
8 }
MoUser实体:
1 public class MoUser {
2
3 private long id;
4 private String userName;
5 private String userPwd;
6
7 public long getId() {
8 return id;
9 }
10
11 public void setId(long id) {
12 this.id = id;
13 }
14
15 public String getUserName() {
16 return userName;
17 }
18
19 public void setUserName(String userName) {
20 this.userName = userName;
21 }
22
23 public String getUserPwd() {
24 return userPwd;
25 }
26
27 public void setUserPwd(String userPwd) {
28 this.userPwd = userPwd;
29 }
30 }
然后创建我们的服务提供端的模块eureka_provider,同样引入eureka依赖不过和server端有点区别:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
再来创建服务提供端要提供的服务UserController,并且实现我们eureka_api模块中的UserInterface接口,代码如下:
1 @RestController
2 public class UserController implements UserInterface {
3
4 @Autowired
5 private HttpServletRequest request;
6
7 @Override
8 public MoRp<List<MoUser>> getUsers(MoRq rq) {
9
10 MoRp<List<MoUser>> rp = new MoRp<>();
11
12 List<MoUser> list = new ArrayList<>();
13 for (int i = 0; i < 5; i++) {
14 MoUser moUser = new MoUser();
15 moUser.setId(i);
16 moUser.setUserName("神牛" + i);
17 list.add(moUser);
18 }
19 rp.setT(list);
20 rp.setStatus(list.size() >= 1 ? 1 : 0);
21 rp.setMessage(list.size() >= 1 ? "" : "暂无数据");
22 return rp;
23 }
24
25 @Override
26 public String getMsg() {
27
28 return "这里是provider,端口:"+ request.getServerPort();
29 }
30 }
这里需要注意的是Controller的两个服务接口中没有再加PostMapping或GetMapping,因为这个由被实现接口申明了;定义好了users和msg服务后,我们还需要能把他们注入到服务注册中心去,因此需要如下application.yml的配置:
1 spring:
2 application:
3 name: eureka-provider #服务名称
4 eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:2001/eureka/ #服务中心地址
8 instance:
9 prefer-ip-address: true
10 instance-id: ${spring.application.name}:${server.port}
11 server:
12 port: 2004
我们还需要在启动类增加如下标记 @EnableEurekaClient ,它表示启动eureka客户端,因为服务提供者相对服务中心来说是属于客户端的存在;当运行eureka_provider项目的时候,我们在注册中心能看到如下信息:
为了保证服务提供端接口没问题,我们可以直接点击eureka-provider:2004,然后增加要方法接口的路径我这里是:http://192.168.153.148:2004/msg,即可得到如下正常访问接口返回的信息:
有了接口服务,我们还需要消费服务,因此创建module项目eureka_consumer,因为这里采用fegin伪客户端的方式来访问我们服务提供端,并且同样需要引入eureka的依赖:
1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-eureka</artifactId>
4 </dependency>
5 <dependency>
6 <groupId>org.springframework.cloud</groupId>
7 <artifactId>spring-cloud-starter-feign</artifactId>
8 </dependency>
然后在service层定义UserService服务并且实现公共接口模块eureka_api中的接口,代码如:
1 @FeignClient(value = "eureka-provider")
2 public interface UserService extends UserInterface {
3
4 }
通过FeignClient来指定调用的服务端应用名称eureka-provider,这名称对应注册在服务中心的Application目录下 ,在Controller层创建一个响应的输出UserController并分别提供两个展示的接口,代码如:
1 @RestController
2 public class UserController{
3
4 @Autowired
5 private UserService userService;
6
7 @GetMapping("/users")
8 public MoRp<List<MoUser>> getUsers(MoRq rq) {
9 return userService.getUsers(rq);
10 }
11
12 @GetMapping("/msg")
13 public String getMsg() {
14 return userService.getMsg();
15 }
16 }
同样Consumer端也需要在application.yml中配置一些信息:
1 spring:
2 application:
3 name: eureka-consumer
4 eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:2001/eureka/ #注册中心地址
8 instance:
9 prefer-ip-address: true
10 instance-id: ${spring.application.name}:${server.port}
11 server:
12 port: 2005
配置基本和provider端差不多,最后需要在启动类申明如下注解:
1 @SpringBootApplication
2 @EnableDiscoveryClient //消费者客户端
3 @EnableFeignClients //feign客户端
4 public class EurekaConsumerApplication {
5 public static void main(String[] args) {
6 SpringApplication.run(EurekaConsumerApplication.class, args);
7 }
8 }
启动eureka_consumer项目后,我们能在注册中心看到它注册进来的信息:
然后通过访问eureka_consumer消费方的接口测试eureka_provider服务提供方的接口数据知否能正常响应,接口地址 http://192.168.153.148:2005/msg :
通过访问consumer得到了provider的结果,这就是服务注册和发现的基本测试流程;至于消费方怎么请求到提供方接口的,我们通过如下手工图可解:
由上面手工图来看,服务中心承担着很重要的角色,通常这种服务中心不仅仅只搭建一个,因此需要搭建一套高可用的服务中心出来;其实很简单provider和consumer配置都不用动,我们只需要在第一节点的eureka-server项目的application.yml中配置下并且在多启动几个不同端口的服务就行了(同一台服务器是多个端口,不同服务器端口可能是一样的):
1 server:
2 port: 2001
3 spring:
4 application:
5 name: eureka-server
6 eureka:
7 client:
8 register-with-eureka: true #配置高可用的时候需要开放自己注册自己
9 fetch-registry: true
10 service-url:
11 defaultZone: http://localhost:2002/eureka/ #注册到端口2002的eureka中
12 # defaultZone: http://localhost:2001/eureka/
13 instance:
14 prefer-ip-address: true
15 instance-id: ${spring.application.name}:${server.port}
16 server:
17 eviction-interval-timer-in-ms: 2000 #剔除失效服务间隔
高可用配置需要注意以下几点:
这里我创建了两个注册中心地址分别为:http://localhost:2001/,http://localhost:2002/;由于之前provider和consumer配置的注册中心地址都是2001端口的,为了验证高可用我们需要访问2002端口注册中心,效果如:
能够看到2002端口有着2001端口同样的注册信息,当我关闭2001端口的应用时,2002还是能够查到provider和consumer的信息,更详细的配置可以参照官网说明。