微服务5:服务注册与发现(实践篇)
★微服务系列
1 服务注册中⼼
前⾯我们对业内⼏种⽐较常见的注册中⼼做了介绍:Eureka、Zookeeper、Consul、Etcd。
并且在各个指标上做了对⽐:注册⽅式(watch\polling)、健康检查、雪崩保护、安全与权限,以及在Spring Cloud、Dubbo、Kubernets 上的⽀持程度。⽅便我们在不同的场景下做正确的技术选型。
4种注册中⼼技术对⽐
指标Eureka Zookeeper Consul Etcd
⼀致性协议AP CP(Paxos算法)CP(Raft算法)CP(Raft算法)
健康检查TTL(Time To Live)TCP Keep Alive TTL\HTTP\TCP\Script Lease TTL KeepAlive
watch/long polling不⽀持watch long polling watch
雪崩保护⽀持不⽀持不⽀持不⽀持
安全与权限不⽀持ACL ACL RBAC
是否⽀持多数据中⼼是否是否
是否有管理界⾯是否(可⽤第三⽅ZkTools)是否
Spring Cloud 集成⽀持⽀持⽀持⽀持
Dubbo 集成不⽀持⽀持⽀持不⽀持
K8S 集成不⽀持不⽀持⽀持⽀持
我们可以看出,四种技术类型对Spring Cloud的⽀持度都很⾼。Spring Cloud是微服务架构的⼀站式解决⽅案,我们平时构建微服务的过程中需要做的的如配置管理、服务发现、负载均衡、断路器、智能路由、控制总线、全局锁、决策竞选、分布式会话和集状态管理等操作。Spring Cloud 为我们提供了⼀套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项⽬的构建。
Spring Cloud包含了多个不同开源产品,来保证⼀站式的微服务解决⽅案,如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Security、Spring Cloud Commons、Spring Cloud Zookeeper、Spring Cloud CLI等项⽬。
2 Spring Cloud 框架下实现
Spring Cloud为服务治理做了⼀层抽象,这样能够⽀持多种不同的服务治理框架,⽐如:Netflix Eureka、Consul。我们这边就以这两个为例⼦,看看服务治理是如何实现。
在Spring Cloud服务治理抽象层的作⽤下,可以⽆缝地切换服务治理实现,且不影响任何其他的服务注册、发现、调⽤逻辑。
所以,下⾯我们通过介绍这两种服务治理的实现来体会Spring Cloud这⼀层抽象所带来的好处。
2.1 Spring Cloud Eureka
Spring Cloud Eureka是Spring Cloud Netflix项⽬下的服务治理模块。⽽Spring Cloud Netflix项⽬是Spring Cloud的⼦项⽬之⼀,主要内容是对Netflix公司⼀系列开源产品的包装,它为Spring Boot应⽤提供了⾃配置的Netflix OSS整合。
通过⼀些简单的注解,开发者就可以快速的在应⽤中配置⼀下常⽤模块并构建庞⼤的分布式系统。它主要提供的模块包括:服务发现(Eureka),断路器(Hystrix),智能路由(Zuul),客户端负载均衡(Ribbon)等。
下⾯,就来具体看看如何使⽤Spring Cloud Eureka实现服务治理。
2.1.1 创建注册中⼼
创建⼀个Spring Cloud项⽬,我们命名为micro-service-center,并在l中引⼊需要的依赖内容:
1<packaging>pom</packaging>
表明这个项⽬中可以没有Java代码,也不执⾏任何代码,只是为了聚合⼯程或者传递依赖,所以可以把src⽂件夹删了。这是⼀个⽗级项⽬,因为我们还要在下⾯建⽴Eureka的注册中⼼、客户端等多个⼦项⽬。
在micro-service-center下,新建⼀个命名为 eureka-service 的Module,依旧是Spring Cloud 项⽬,建完之后,l做如下改动:
1<!--    在⼦⼯程中添加⽗⼯程名称-->
2<parent>
3<groupId>com.microservice</groupId>
4<artifactId>center</artifactId>
5<version>1.0.0</version>
6</parent>
7
8
9<dependencies>
10<!--  加⼊ eureka 服务 -->
11<dependency>
12<groupId>org.springframework.cloud</groupId>
13<artifactId>spring-cloud-netflix-eureka-server</artifactId>
14</dependency>
15</dependencies>
改完之后,回到⽗项⽬micro-service-center,修改pom中的信息:
1<groupId>com.microservice</groupId>
2<artifactId>center</artifactId>
3<packaging>pom</packaging>
4<version>1.0.0</version>
5<name>center</name>
6<description>Demo project for Spring Boot</description>
7
8<!--    在⽗⼯程添加⼦⼯程名称-->springboot推荐算法
9<modules>
10<module>eureka-service</module>
11<module>eureka-client</module>
12</modules>
对两个项⽬进⾏clean + install,应该是成功的。
eureka-service我们是作为注册中⼼来⽤的,所以在它的主类Application中加⼊@EnableEurekaServer注解,就能开启注册中⼼功能。
1 @SpringBootApplication
2 @EnableEurekaServer
3public class ServiceApplication {
4public static void main(String[] args) {
5        SpringApplication.run(ServiceApplication.class, args);
6        System.out.println("Start Eureka Service");
7    }
8 }
但是默认情况下,该注册中⼼也会把⾃⼰当做客户端,那就变成⾃⼰注册⾃⼰了,这个是可以剔除的,我们看⼀下它的YAML中的详细配置,注释⽐较清楚:
1 server:
2  port: 1000
3 spring:
4  application:
5    name: eureka-server
6 eureka:
7  instance:
8    hostname: localhost
9  client:
10    register-with-eureka: false  # 不作为客户端进⾏注册
11    fetch-registry: false  # 不获取注册列表
12    service-url:  # 注册地址,客户端需要注册到该地址中
13      defaultZone: ${eureka.instance.hostname}:${server.port}/eureka/
2.1.2 创建客户端
⽬前服务中⼼还是空的,所以我们创建⼀个能够提供服务的客户端,并将其注册到注册中⼼去。
同样的,我们创建⼀个Spring Cloud的⼦项⽬,命名为eureka-client,l中的配置如下:
1<!--    在⼦⼯程中添加⽗⼯程名称-->
2<parent>
3<groupId>com.microservice</groupId>
4<artifactId>center</artifactId>
5<version>1.0.0</version>
6</parent>
7
8
9<dependencies>
10
11<!--    加⼊ eureka 服务 -->
12<dependency>
13<groupId>org.springframework.cloud</groupId>
14<artifactId>spring-cloud-netflix-eureka-server</artifactId>
15</dependency>
16
17<dependency>
18<groupId>org.projectlombok</groupId>
19<artifactId>lombok</artifactId>
20</dependency>
21
22</dependencies>
在应⽤主类Application⽂件中通过加上@EnableDiscoveryClient注解,该注解保证当前服务被Eureka当成provider发现。
1 @SpringBootApplication
2 @EnableDiscoveryClient
3public class ClientApplication {
4public static void main(String[] args) {
5        SpringApplication.run(ClientApplication.class, args);
6        System.out.println("start client!");
7    }
8 }
在YAML⽂件上加上如下配置:
1 server:
2  port: 1001
3 spring:
4  application:
5    name: eureka-client
6 eureka:
7  client:
8    service-url:  # 这边就保证了注册到 eureka-service 这个注册中⼼去
9      defaultZone: localhost:1000/eureka/
spring.application.name属性,指定了微服务的名称,在调⽤的时候可以通过该名称进⾏服务访问。eureka.client.serviceUrl.defaultZone属性对应服务注册中⼼的配置内容,指定服务注册中⼼的位置。
⼤家看到,这边端⼝设置为1001,那是因为要在本机上测试服务提供⽅和服务注册中⼼,所以server的port属性需设置不同的端⼝。
最后,我们再写⼀个接⼝,通过DiscoveryClient对象,在客户端中获取注册中⼼的所有服务信息。
1 @Controller
2 @RequestMapping("/eurekacenter")
3public class EuServiceController {
4
5    @Autowired
6    DiscoveryClient discoveryClient;
7
8/**
9    * 获取注册服务信息
10*/
11    @RequestMapping(value = "/service", method = {RequestMethod.GET})
12    @ResponseBody
13public String getServiceInfo() {
14return  "service:"+Services()+" , memo:"+discoveryClient.description();
15    }
16 }
如上图所⽰,⽅括号中的eureka-client通过Spring Cloud定义的 getServiceInfo 接⼝在eureka的实现中获取到的所有服务清单,他是⼀个String 的List,如果注册了多个提供者,就会全部显⽰。
2.2 Spring Cloud Consul
Consul ⽤于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的⽅案,Consul 的⽅案更具“⼀站式”特征,内置了服务注册与发现框架、分布⼀致性协议实现、健康检查、Key/Value 存储、多数据中⼼⽅案,不再需要依赖其它⼯具(⽐如 ZooKeeper 之类的)。⽽Spring Cloud Consul ,是将其作为⼀个整体,在微服务架构中为我们的基础设施提供服务发现和服务配置的⼯具。
2.2.1 Consul 的优势
1、使⽤ Raft 算法来保证⼀致性, ⽐复杂的 Paxos 算法更直接。
2、⽀持多数据中⼼,内外⽹的服务采⽤不同的端⼝进⾏监听。多数据中⼼集可以避免单数据中⼼的单点故障,⽽其部署则需要考虑⽹络延迟, 分⽚等情况等。 zookeeper 和 etcd 均不提供多数据中⼼功能的⽀持,上⾯表格中有体现。
3、⽀持健康检查。
4、⽀持 http 和 dns 协议接⼝。 zookeeper 的集成较为复杂, etcd 只⽀持 http 协议。
5、官⽅提供 web 管理界⾯, etcd ⽆此功能。
2.2.2 Consul的特性
1、服务发现
2、健康检查
3、Key/Value存储
4、多数据中⼼
2.2.3 安装Consul注册中⼼
2、解压后复制到⽬录 /usr/local/bin 下
3、启动终端,先看下啥版本的
1wengzhihua@B000000147796DS ~ % consul --version
2Consul v1.10.4
3 Revision 7bbad6fe
4 Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
1 wengzhihua@B000000147796DS ~ % consul agent -dev
2 ==> Starting
3            Version: '1.10.4'
4            Node ID: '6db154b4-62ff-e67d-e745-1a7270fa1ce8'
5          Node name: 'B000000147796DS'
6        Datacenter: 'dc1' (Segment: '<all>')
7            Server: true (Bootstrap: false)
8        Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
9      Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
10            Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
我们可以看到,现在没有客户端注册上来,只有⼀个⾃⾝的实例。
2.2.4 创建服务提供者
由于Spring Cloud Consul项⽬的实现,我们可以轻松的将基于Spring Boot的微服务应⽤注册到Consul上,并通过此实现微服务架构中的服务治理。
我们在micro-service-center下新建⼀个cloud项⽬consul-client,该项⽬pom⽂件添加如下:
1<!--    在⼦⼯程中添加⽗⼯程名称-->
2<parent>
3<groupId>com.microservice</groupId>
4<artifactId>center</artifactId>
5<version>1.0.0</version>
6</parent>
7
8<dependencies>
9<!--        Consul服务发现-->
10<dependency>
11<groupId>org.springframework.cloud</groupId>
12<artifactId>spring-cloud-starter-consul-discovery</artifactId>
13</dependency>
14<!--        Consul健康检查-->
15<dependency>
16<groupId>org.springframework.boot</groupId>
17<artifactId>spring-boot-starter-actuator</artifactId>
18</dependency>
19</dependencies>
然后修改⼀下l的配置信息,将consul配置写⼊,注释应该很清楚了,如下:
1 spring:
2  application:
3    name: consul-producer # 当前服务的名称
4  cloud:
5    consul: # 以下为Consuk注册中⼼的地址,如果安装的不是这个host和port,这边可以调整
6      host: localhost
7      port: 8500
8 server:
9  port: 8501 # 当前服务的端⼝
同样的,我们要在应⽤主类Application⽂件中通过加上@EnableDiscoveryClient注解,该注解保证当前服务被Consul当成provider发现。
⼤家看到这个做法跟Eureka⼀样,因为Spring Cloud对服务治理做的⼀层抽象,所以可以屏蔽Eureka和Consul服务治理的实现细节,
程序上不需要做改变,只需要引⼊不同的服务治理依赖,并配置相关的配置属性就能轻松的将微服务纳⼊Spring Cloud的各个服务治理框架
中。
1 @SpringBootApplication
2 @EnableDiscoveryClient
3public class ConsulClientApplication {
4public static void main(String[] args) {
5        SpringApplication.run(ClientApplication.class, args);
6    }
7 }
修改完成之后,我们就可以把这个服务提供者启动了,然后再去注册中⼼查看服务的注册情况,就可以看到被注册进来的Provider(consul-producer):
3 总结
除了 Eureka、Consul,还有其他的的注册中⼼技术,如Zookeeper、Nocas等。但⽆论何种注册中⼼技术,本质上都是为了解决微服务中的如下问题:
解耦服务之间相互依赖的细节
我们知道服务之间的远程调⽤必须要知道对⽅的IP、端⼝信息。我们可以在调⽤⽅直接配置被调⽤⽅
的IP、端⼝,这种调⽤⽅直接依赖IP、端⼝的⽅式存在明显的问题,如被调⽤的IP、端⼝变化后,调⽤⽅法也要同步修改。
通过服务发现,将服务之间IP与端⼝的依赖转化为服务名的依赖,服务名可以根据具微服务业务来做标识,因此,屏蔽、解耦服务之间的依赖细节是服务发现与注册解决的第⼀个问题。
对微服务进⾏动态管理
在微服务架构中,服务众多,服务之间的相互依赖也错综复杂,⽆论是服务主动停⽌,意外挂掉,还是因为流量增加对服务实现进⾏扩容,这些服务数据或状态上的动态变化,都需要尽快的通知到被调⽤⽅,被调⽤⽅才采取相应的措施。因此,对于服务注册与发现要实时管理者服务的数据与状态,包括服务的注册上线、服务主动下线,异常服务的剔除。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。