1、服务治理
服务治理是微服务架构的最核心和基础模块,用于实现各个微服务间的自动化注册和发现。服务治理解决了微服务系统架构中微服务实例配置维护困难问题。服务治理框架围绕服务注册和服务发现机制来完成对微服务应用实例的自动化管理
2、 服务注册
构建注册中心,微服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通讯协议告知注册中心,注册中心按照服务名分类组织服务清单。
3、服务发现
在服务治理架构体系下,服务间的调用不再通过指定服务的实例地址,而是通过服务名来调用。在调用服务时,服务调用方并不知道服务的实例地址。服务调用方需要向注册中心咨询服务,获取服务清单,用于对具体服务实例的访问。
4、 Spring Cloud Eureka
Spring Cloud使用Netflix Eureka来实现服务的注册和发现,它即包括服务端组件,又包含了客户端组件。
Eureka Server 又称服务注册中心,支持高可用配置,依托强一致性提供良好的服务实例可用性。Eureka Client 主要处理服务的注册和发现,通过定期向服务注册中心发送心跳刷新自己的服务租约,同时又能从注册中心查询当前注册的服务信息缓存本地并周期性刷新服务注册信息。
Eureka Client 主要处理服务的注册和发现,Client向注册中心注册自身提供的服务并周期性发送心跳到注册中心更新服务租约,同时还能从主持中心查询当前注册的服务信息并缓存到本地
核心要素:服务注册中心、服务提供者、服务消费者
实现机制:
服务注册中心互相注册形成高可用集群,失效剔除(定时任务,定时剔除没有续约的服务实例)
服务提供者:注册、续约(定时心跳)、下线,服务同步(注册到一个注册中心,会将请求转发给集群其他注册重新)
服务消费者:从注册中心拉取服务并缓存清单
5、Eurreka 搭建
环境:org.springframework.boot 2.1.7.RELEASE Spring Cloud.version Greenwich.SR2
5.1 Eureka Server 搭建
引入Spring Boot、Spring Cloud、Eureka Server依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.newbie.parent</groupId>
<artifactId>newbie-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>eureka-server</artifactId>
<name>eureka-server</name>
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<!--管理依赖jar包-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
通过@EnableEurekaServer注解开启Eureka服务注册中心
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置注册中心参数
server.port=1111
#实例url指向 主机ip+端口号 不加的话url指向的依然是主机名+端口号
eureka.instance.hostname=localhost
#设置是否向注册中心注册
eureka.client.register-with-eureka=true
#是否向注册中心发送心跳查询服务
eureka.client.fetch-registry=true
#eureka默认服务地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
5.2 Eureka Client搭建
引入Spring Boot、Spring Cloud、Eureka Client依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.newbie.parent</groupId>
<artifactId>newbie-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>hello-consumer</artifactId>
<packaging>jar</packaging>
<name>hello-consumer</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
通过@EnableDiscoveryClient激活Eureka DiscoveryClient实现,以便能输出服务信息
@SpringBootApplication
@EnableDiscoveryClient
public class HelloConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(HelloConsumerApplication.class, args);
}
}
添加客户名、注册中心地址
spring.application.name=hello-consumer
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
编写测试Controller,测试输出服务信息
...
...
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String home() {
List<ServiceInstance> instanceList = client.getInstances("qt-eurekaservice");
for (ServiceInstance instance : instanceList) {
LOG.info("/hello,host:" + instance.getHost() + ",serviceId:" + instance.getServiceId());
}
return "hello world!";
}
...
...
...
6、高可用注册中心实现
Eureka 服务治理体系下,应用即是服务提供方,也是服务消费方,Eureka Server通过向其他注册中心注册自己,这样就形成了一组互相组成自己的服务注册中心,以实现服务清单的同步,达到高可用的效果。
创建注册中心集群peer1和peer2
application-peer1.properties
spring.application.name=eureka-server
server.port=1111
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/
application-peer2.properties
spring.application.name=eureka-server
server.port=1112
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
多节点本地启动
mvn spring-boot:run -Dspring-boot.run.profiles=peer1
mvn spring-boot:run -Dspring-boot.run.profiles=peer2
7、服务治理之服务发现与消费搭建
引入Spring Boot、Spring Cloud、Eureka Client、Ribbon依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.newbie.parent</groupId>
<artifactId>newbie-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>ribbon-consumer</artifactId>
<name>ribbon-consumer</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
通过注解通过@EnableDiscoveryClient激活Eureka DiscoveryClient实现,以便获得服务发现能力,同时创建RestTemplate Spring Bean 实例,同时使用@LoadBalanced注解开启客户端负载均衡。
@SpringBootApplication
@EnableDiscoveryClient
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 ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String toHelloConsumer() {
return restTemplate.getForEntity("http://HELLO-CONSUMER/hello", String.class)
.getBody();
}
}
本地启动应用进行服务发现与消费调试
启动eureka server
mvn spring-boot:run -Dspring.profiles.active=peer1 -Ddebug
启动eureka 服务提供者
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8082"
启动ribbon
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8083"
访问/ribbon-consumer,验证ribbon客户端的负载均衡