Spring Cloud服务注册与发现
Spring Cloud集成了搭建分布式服务一系列框架,如服务注册与发现Eureka,熔断器Hystrix,路由网关Zuul,链路追踪zipkin,今天主要讲解Eureka的使用。
Eureka是什么?
Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现。也是springcloud体系中最重要最核心的组件之一,我们通过下面这样图就可以了解
1)服务提供方向Eureka注册自己的服务,
2)消费者向Eureka获取自己需要的服务,和提供方建立连接
3) 如果服务方出现故障,Eureka会自动将服务方从注册列表中删除
搭建项目
创建Eureka服务
首先创建一个Maven项目,指定spring boot,spring cloud 版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR2</spring-cloud.version> </properties>
创建一个模块,我们称为EurekaServer,使用Eureka只需要引入maven包,然后启动项目就可以了,很方面,如下:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
配置application.yml文件
server: port: 8081 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring: application: name: eurka-server
添加注解@EnableEurekaServer,并启动EurekaServer
@SpringBootApplication @EnableEurekaServer public class EurakaServerApplication { public static void main(String[] args) { SpringApplication.run(EurakaServerApplication.class, args); } }
启动EurekaServer,地址为:http://localhost:8081/eureka
创建提供方服务
添加maven依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
创建服务接口
@RestController public class AirportController { @Autowired private AirportService airportService; @RequestMapping("/getAirport") public AirportBean getAirport(@RequestParam("threeCode") String threeCode) { return airportService.getAirport(threeCode); } } @Service public class AirportService { @Value("${server.port}") private int port; public AirportBean getAirport(String threeCode) { AirportBean bean = new AirportBean(); bean.setName("北京首都国际机场"); bean.setThreeCode(threeCode); bean.setPort(port); return bean; } } public class AirportBean { private String threeCode; private String name; private int port; }
修改application.yml文件
<code>server: port: 8082 spring: application: name: dynamic-service eureka: client: serviceUrl: defaultZone: http://localhost:8081/eureka/</code>
添加@EnableEurekaClient注解,这里我们为了方便演示负载均衡,同时也启动了两个实例,端口分别为8082,8083
@SpringBootApplication @EnableEurekaClient public class DynamicServiceApplication { public static void main(String[] args) { SpringApplication.run(DynamicServiceApplication.class, args); } }
创建服务消费方
我们再项目下再新建一个模块,称为springcloudclient,添加maven依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
这里我们使用了feign的服务调用方式,Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign,ribbon类似一种rest风格的API调用方式,而feign整合了ribbon,具有负载均衡的能力,通过注解的方式,使代码看起来更加简洁,另外feign整合了Hystrix,具有熔断的能力
调用服务方的接口
@RestController public class AirportFeignController { @Autowired private AirportFeignService airportFeignService; @RequestMapping(value = "/getAirport",method = RequestMethod.GET) public AirportBean getAirport(@RequestParam("threeCode") String threeCode) { return airportFeignService.getAirport(threeCode); } } @FeignClient(value = "dynamic-service", fallback = AirportFeignFallbackService.class) public interface AirportFeignService { @RequestMapping(value = "/getAirport",method = RequestMethod.GET) public AirportBean getAirport(@RequestParam("threeCode") String threeCode); } // 服务失败后熔断,调用的方法 public class AirportFeignFallbackService implements AirportFeignService { @Override public AirportBean getAirport(String threeCode) { return null; } } public class AirportBean { private String threeCode; private String name; private int port; }
配置application.yml文件
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8084 spring: application: name: service-feign
添加@ EnableEurekaClient,@EnableDiscoveryClient, @EnableFeignClients注解,端口为8084,
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableFeignClients public class SpringCloudServerApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudServerApplication.class, args); } }
好了下面可以演示springcloud的服务注册与发现了,通过上面的例子,我们启动了Eureka服务,分别为:8081,同时启动了两个服务提供方,注册到Eureka中,端口分别为8082和8083,接着我们启动了一个服务消费方,端口为8084,我们分别启动他们
打开Eureka的服务页面:http://localhost:8081
可以发现有两个服务方已经注册上了,我们调用消费方的接口,发现消费方会使用负载均衡的方式分别访问服务方
注册中心没用集群吗?单点问题怎么办
是的,线上环境一般配置集群,你可以配置两个Eureka服务,相互监控
我配置了spring-cloud-starter-netflix-eureka-server后一直下载不了
使用官方的Finchley.SR2版本,这里都提供了默认的版本