微服务架构的服务治理工作可以由Eureka来完成。它本身用Java语言编写,实现了服务的注册与发现,并且自身内置了Ribbon负载均衡器。
Eureka的使用
Eureka包含了服务端实现和客户端实现,服务端向注册中心登记一个服务;客户端向注册中心索要服务的所有清单。
建立Eureka注册中心
第一步:创建一个SpringBoot项目,我的版本2.7.0 并引入下列依赖
<!-- 引入Eureka服务依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
需要注意的是,SpringBoot、SpringCloud、Eureka版本要对应,否则会出错,SpringBoot与SpringCloud对应的版本可以在spring.io/projects/sp… 查看,SpringCloud与Eureka对应版本在github.com/spring-clou… 查看。
第二步:配置注册中心
server.port=1111
spring.application.name=hello-service
#指定服务名
eureka.instance.hostname=peer1
#设置不需要将当前服务注册到注册中心
eureka.client.register-with-eureka=false
#设置不需要检索服务(因为本身就是注册中心)
eureka.client.fetch-registry=false
#设置客户端注册服务的地址
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
这个地方注意别忘了将服务名
peer1映射到hosts文件中,大家都懂。
第三步:在启动类上添加@EnableEurekaServer注解
第四部:启动程序,通过 http://peer1:1111 地址访问注册中心
创建一个服务登记到注册中心
第一步:同样的创建一个SpringBoot2.7.0项目,并引入下列依赖
<!-- 引入Eureka客户端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
如果疑惑为什么是客户端依赖,是因为对于注册中心来说,无论是提供服务方还是消费服务方都是客户端,只不过分为服务客户端、消费客户端
第二步:配置服务客户端参数
spring.application.name=myservice
#设置要向哪个地址注册服务
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/
第三步:在启动类上添加@EnableDiscoveryClient注解
第四步:启动程序,刷新刚刚的注册中心页面
成功将一个服务注册到注册中心
创建一个服务的消费者
第一步:创建一个消费者SpringBoot项目,引入springcloud以及eureka客户端依赖
第二步:配置服务客户端参数
第三步:创建一个restful请求对象,并为其赋予ribbon负载均衡的能力,然后在启动类添加@EnableDiscoveryClient注解
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}
第四步:编写一个controller用来消费服务
@RestController
public class ConsumerContrller {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/consumer",method = RequestMethod.GET)
public String helloConsumer(){
return restTemplate.getForEntity("http://myservice/hello",String.class).getBody();
}
}
这里可以直接通过调用对应的服务名myservice找到我们需要的服务实例,因为ribbon已经帮我们做了解析服务实例的操作。最后浏览器访问成功调用myservice服务
现在已经完成了最简单的服务注册与发现,那么Eureka是如何支持高可用和一致性的呢?当服务发生故障如何解决?很显然单节点的注册中心无法满足这个需求。所以接下来就搭建一个高可用的注册中心集群来应对无法预测的故障。
Eureka集群搭建
首先要注释或删除掉上面提到过的两条配置
#设置不需要将当前服务注册到注册中心
eureka.client.register-with-eureka=false
#设置不需要检索服务(因为本身就是注册中心)
eureka.client.fetch-registry=false
Eureka的高可用实现需要不同的注册中心将自己也作为一个服务注册,这样做是为了实现各自包含的服务彼此能够同步,即使有其中一个注册中心故障了,其他注册中心也能正常工作,这样就实现了高可用。
现在因为要搭建两个服务中心,所以创建两个application-*.properties配置文件application-peer1.properties、application-peer2.properties如下
#peer1
server.port=1111
spring.application.name=hello-service
eureka.instance.hostname=peer1
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:1112/eureka/
#peer2
server.port=1112
spring.application.name=hello-service
eureka.instance.hostname=peer2
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:1111/eureka/
记得将peer1、peer2 加到hosts文件\
将peer1注册到peer2服务中心,peer2注册到peer1服务中心。然后这两个注册中心会进行服务清单同步。最终访问注册中心peer1和peer2结果如下
peer1:
peer2:
现在启动两个之前创建的服务的实例(端口分别为8081、8082)注册到服务中心peer1
到现在为止,已经搭建好了注册中心,并且也在其中登记了服务。接下来就启动消费者客户端进行测试
在浏览器中访问消费服务的接口,从相同服务的两个运行实例中可以看到已经实现了负载均衡。