又称服务中心,管理各种服务功能包括 服务的注册、发现、熔断、负载、降级
等。
注册中心
来调用。通过服务中心来获取服务你不需要关注你调用的项目IP地址,由几台服务器组成,每次直接去服务中心获取可以使用的服务去调用既可。 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S
的设计架构。
Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的 其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接 。这样系统的维护人员就可以 通过 Eureka Server 来监控系统中各个微服务是否正常运行 。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。
上图简要描述了Eureka的基本架构,由3个角色组成:
1.创建一个基础的Spring Boot工程,pom中添加依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 引入Eureka-server相关jar--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2.启动代码中添加 @EnableEurekaServer
注解
@SpringBootApplication @EnableEurekaServer public class SpringCloudEurekaApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaApplication.class, args); } }
3.默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,在 application.properties
添加以下配置:
spring.application.name=Eureka Server server.port=7001 #表示是否将自己注册到Eureka Server,默认为true eureka.client.register-with-eureka=false #表示是否从Eureka Server获取注册信息,默认为true eureka.client.fetch-registry=false #设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka ;多个地址可使用 , 分隔 eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
application.yml形式(下面不再给出)
eureka: client: fetch-registry: register-with-eureka: false serviceUrl: defaultZone: http://localhost:${server.port}/eureka/ server: port: 7001 spring: application: name: Eureka Server
启动工程后,访问: http://localhost :7001/ 可以看到没有任何服务
创建提供服务的客户端,并向服务注册中心注册自己。实现一个RESTful API,通过传入两个参数a和b,最后返回a + b的结果
1.创建一个基础的Spring Boot工程,pom中添加依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2.实现 /add
请求处理接口,通过 DiscoveryClient
对象,在日志中打印出服务实例的相关内容
@RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/add" ,method = RequestMethod.GET) public Integer add(@RequestParam Integer a, @RequestParam Integer b) { ServiceInstance instance = client.getLocalServiceInstance(); Integer r = a + b; logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r); return r; } }
3.启动代码中添加 @EnableDiscoveryClient
注解,该注解能激活Eureka中的 DiscoveryClient
实现,才能实现Controller中对服务信息的输出。
@SpringBootApplication @EnableEurekaServer public class SpringCloudEurekaApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaApplication.class, args); } }
4.在 application.properties
添加以下配置:
#可以指定微服务的名称后续在调用的时候只需要使用该名称就可以进行服务的访问。 spring.application.name=Eureka Client server.port=8001 #端口 #属性对应服务注册中心的配置内容,指定服务注册中心的位置 eureka.client.serviceUrl.defaultZone=http://localhost:7001/eureka/
启动工程后,再次访问: http://localhost :7001/ 可以看到定义的服务被注册了
默认情况下,如果Eureka Server在 90秒
没有收到Eureka客户的续约,它会将实例从其注册表中删除。但这种做法的不好之处在于, 客户端已经停止了运行,但仍然在注册中心的列表中。 虽然通过一定的负载均衡策略或使用 熔断器 可以让服务正常进行,但有没有方法让注册中心马上知道服务已经下线呢?
划红线的地址 eureka.client.instance.instance-id
下面是下线一个hello-service的例子。
下图是用postman 发送delete请求
所以,可以 先停掉服务,再发送请求将其从列表中移除。
http://127.0.0.1:7001/eureka/apps/config-server/WINDOWS-61L7RBP:config-server:8769
如果你的eureka客户端是是一个spring boot应用,可以通过调用以下代码通知注册中心下线。
DiscoveryManager.getInstance().shutdownComponent();
例子如下,在eureka client 中
@RestController public class HelloController { @Autowired private DiscoveryClient client; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() { java.util.List<ServiceInstance> instances = client.getInstances("hello-service"); return "Hello World"; } @RequestMapping(value = "/offline", method = RequestMethod.GET) public void offLine(){ DiscoveryManager.getInstance().shutdownComponent(); } }
GET 请求 127.0.0.1:6020/offline