服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册与发现。
web
1.服务注册:spring
在服务治理框架中,一般会构建一个注册中心,每一个服务单元向注册中心登记本身提供的服务,将主机与端口号、缓存
版本号、通讯协议等一些附件信息告知注册中心,注册中心按服务名称分类组织服务清单,例如:架构
2.服务发现:app
调用方须要向服务注册中心咨询服务,并获取全部服务的实例清单,以实现对具体服务实例的访问。负载均衡
Spring Cloud Euraka使用Netflexi Euraka来实现服务的注册与发现,它既包含了框架
服务端的组件也包含了客户端的组件。spring-boot
Euraka 服务端:即服务注册中心。微服务
Euraka 客户端:主要处理服务的注册与发现。Euraka客户端向注册中心注册自身提供的服务并fetch
周期性地发送心跳来更新它的服务租约。同时,他能从服务端查询当前注册的服务信息并把它们
缓存到本地并周期性地更新服务状态。
pom.xml中引入必要依赖:
<dependencies> <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.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
启用服务注册中心:
//启动一个服务注册中心,提供给其余应用进行对话。 //在默认设置下,该服务注册中心也会将本身做为客户端尝试注册它本身 @EnableEurekaServer @SpringBootApplication public class TangcloudApplication { public static void main(String[] args) { SpringApplication.run(TangcloudApplication.class, args); } }
禁用默认的客户端注册行为:
#设置服务注册中心端口 server.port=1111 eureka.instance.hostname=localhost #不向注册中心注册本身 eureka.client.register-with-eureka=false #注册中心不须要去检索服务 eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eurka/
pom.xml:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
controller:
@RestController public class HelloController { @Autowired private DiscoveryClient client; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() { ServiceInstance serviceInstance = client.getLocalServiceInstance(); System.out.println("/hello, host: " + serviceInstance.getHost() + ", service_id: " + serviceInstance.getServiceId()); return "Hello World!"; } }
@EnableDiscoveryClient //激活DiscoveryClient实现 @SpringBootApplication public class Service1Application { public static void main(String[] args) { SpringApplication.run(Service1Application.class, args); } }
application.properties文件:
server.port=9669 spring.application.name=hello-service eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
Euraka高可用实际上就是将本身做为服务向其余服务注册中心注册本身,这样就能够
造成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用效果。
构建一个服务注册中心集群:
1)建立application-peer1.properties,做为peer1服务中心的配置:
pring.application.name=eureka-server server.port=1111 eureka.instance.hostname=peer1 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.client.service-url.defaultZone=http://peer2:1112/eureka/
2)建application-peer1.properties,做为peer1服务中心的配置:
spring.application.name=eureka-server server.port=1112 eureka.instance.hostname=peer2 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.client.service-url.defaultZone=http://peer1:1111/eureka/
3)服务提供方的配置:
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
下面构建一个服务消费者,它能够发现服务及消费服务。其中服务的发现任务由Eureka的客户端完成。
Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它在Eureka发现服务的基础上,实现了一套对服务
的选择策略。
首先,建立一个Spring Boot工程,并在以前hello-service的pom.xml基础上新增:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
启动类:
@SpringBootApplication @EnableDiscoveryClient //让该应用注册为Eureka客户端,得到服务发现的能力 public class ConsumerApplication { @Bean @LoadBalanced //开启客户端负载均衡 RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
application.properties
server.port=9671 spring.application.name=ribbon-consumer eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
controller:
@RestController public class ConsumerController { @Autowired RestTemplate restTemplate; //经过它来调用service-hello服务的/hello接口 @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET) public String helloConsumer() { return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody(); } }