什么是服务治理
在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,
管理服务与服务之间依赖关系,
可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
什么是服务注册与发现
在服务注册与发现中,有一个注册中心,当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。
另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,让后在实现本地rpc调用远程。
一、搭建 erueka 注册中心环境
1、创建springboot 项目,springcloud-erueka
2、maven 全部依赖信息
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springcloud-erueka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-erueka</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 管理依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--SpringCloud eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、yml 配置
###服务端口号
server:
port: 8100
###eureka 基本信息配置
eureka:
instance:
hostname: 127.0.0.1 # 注册到eurekaip地址
client:
serviceUrl:
#注册中心地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false #因为自己是为注册中心,不需要自己注册自己
fetch-registry: false #因为自己是为注册中心,不需要检索服务
4、启动类添加 @EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class SpringcloudEruekaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudEruekaApplication.class, args);
}
}
5、启动项目访问 ,http://localhost:8100/ (ip+端口)
出现如下搭建成功
二、搭建消费和服务项目
1、创建springboot项目
springcloud-member ,springcloud-order ,配置都相同
2、maven 配置
<!-- 管理依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot整合eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
3、yml 配置
服务名称不同
pringcloud-order --> name: app-order
pringcloud-member --> name: app-member
其他相同,如下:修改服务名称同上
###服务启动端口号
server:
port: 8000
spring:
application:
name: app-order # 服务名称(服务注册到eureka名称)
### 服务注册
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka # 注册中心eureka地址
register-with-eureka: true # 因为该应用为注册中心,不会注册自己
fetch-registry: true # 是否需要从eureka上获取注册信息
4、启动类添加@EnableEurekaClient 和 注入RestTemplate
所有客服端相同
@SpringBootApplication
@EnableEurekaClient //Eureka 客户端
public class SpringcloudOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudOrderApplication.class, args);
}
/**
* TODO RestTemplate = rest,http风格的,api调用工具
*
* @return org.springframework.web.client.RestTemplate
* @date 2019/12/6 0006 12:02
*/
@Bean //注入springboot容器
@LoadBalanced //让RestTemplate在请求时拥有客户端负载均衡的能力
RestTemplate restTemplate() {
return new RestTemplate();
}
}
5、生产者 member项目添加方法 getMember
@RestController
public class memberController {
@RequestMapping("getMember")
public String getMember(){
return "memberController 的Api 接口";
}
}
结构如下
6、消费者 order 项目添加方法调用生产者方法
http://app-member/getMember 中的 app-member 等于pringcloud-member 服务名,也就是serviceId
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getorder")
public String getOrder() {
// order 使用rpc 远程调用技术 调用 会员服务
String memberUrl = "http://app-member/getMember";
//调用接口
String result = restTemplate.getForObject(memberUrl, String.class);
System.out.println("会员服务调用订单服务,result:" + result);
return result;
}
}
7、启动项目,先启动erueka,在启动客服端
8、测试结果
http://win-cdi45048l28 等同与Ip,可以写为ip
三、搭建高可用,集群
创建两个erueka项目集群,创建项目同一,看上方
1、客服端集群默认使用轮训机制,直接注册多个相关name的服务即可
2、注册中心集群默认主从模式,当主宕机了,自动切换备机
1、erueka-A 注册中心,yml配置
###服务端口号
server:
port: 8100
spring:
application:
name: eureka-server # 集群的所有erueka 项目名称必须相同
###eureka 基本信息配置
eureka:
instance:
hostname: 127.0.0.1 # 注册到eurekaip地址
client:
serviceUrl:
#注册中心地址
defaultZone: http://127.0.0.1:8200/eureka/ # 集群设置为另一台或者多台eureka注册中心,多个集群,逗号分隔
register-with-eureka: true # 集群把自己注册到另外一台eureka注册中心,设置为true
fetch-registry: true # 集群需要检索服务,设置为true'
2、erueka-B 注册中心,yml配置
端口: 8200 ,注册到http://127.0.0.1:8100/eureka/
###服务端口号
server:
port: 8200
spring:
application:
name: eureka-server # 集群的所有erueka 项目名称必须相同
###eureka 基本信息配置
eureka:
instance:
hostname: 127.0.0.1 # 注册到eurekaip地址
client:
serviceUrl:
#注册中心地址
defaultZone: http://127.0.0.1:8100/eureka/ # 集群设置为另一台或者多台eureka注册中心,多个集群,逗号分隔
register-with-eureka: true # 集群把自己注册到另外一台eureka注册中心,设置为true
fetch-registry: true # 集群需要检索服务,设置为true'
3、客服端使用集群版erueka
defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka # 配置为多个地址即可
如:
server:
port: 8000
spring:
application:
name: app-member
###单机地址
#eureka:
# client:
# service-url:
# defaultZone: http://localhost:8100/eureka
###集群地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka
register-with-eureka: true
fetch-registry: true
这里就不演示了,很简单的
四、erueka 自我保护机制
1、缓存机制
消费者启动的时候,使用服务别名,会发送一个rest请求到服务注册中心获取对应的服务信息,让后会缓存到本地jvm客户端中,同时客户端每隔30秒从服务器上更新一次。
可以通过 fetch-inte vall-seconds=30参数进行修以
通过eureka.client .registry该参数默认值为30, 单位为秒。
## 修改从注册中心获得的地址在本地的缓存时间
fetch-inte vall-seconds=30 || eureka.client.registry=30
自我保护机制
默认情况下,EurekaClient会定时向EurekaServer端发送心跳,如果EurekaServer在一定时间内没有收到EurekaClient发送的心跳,便会把该实例从注册服务列表中剔除(默认是90秒),但是在短时间内丢失大量的实例心跳,这时候EurekaServer会开启自我保护机制,Eureka不会踢出该服务。
关闭自我保护机制,服务端yml 添加配置
server:
# 测试时关闭自我保护机制,保证不可用服务及时踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 # 踢出执行的线程时间间隔
完整如下:
eureka:
instance:
###注册中心ip地址
hostname: 127.0.0.1
client:
serviceUrl:
##注册地址
defaultZone: http://${eureka.instance.hostname}:8100/eureka/
####因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
register-with-eureka: false
###因为自己是注册中心, 不需要去检索服务信息
fetch-registry: false
server:
# 测试时关闭自我保护机制,保证不可用服务及时踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 # 踢出执行的线程时间间隔
关闭自我保护机制,客户端yml 添加配置
# 心跳检测检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
instance:
###Eureka客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端自己会按照该规则)
lease-renewal-interval-in-seconds: 1
####Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
lease-expiration-duration-in-seconds: 2
完整如下:
eureka:
client:
service-url:
##### 当前会员服务注册到eureka服务地址
# defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka
defaultZone: http://localhost:8100/eureka
### 需要将我的服务注册到eureka上
register-with-eureka: true
####需要检索服务
fetch-registry: true
registry-fetch-interval-seconds: 30
# 心跳检测检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
instance:
###Eureka客户端向服务端发送心跳的时间间隔,单位为秒(客户端告诉服务端自己会按照该规则)
lease-renewal-interval-in-seconds: 1
####Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
lease-expiration-duration-in-seconds: 2
关闭自我保护机制的目的是为了本地开发,
解决项目经常重新启动,eureka不会自动剔除,及时更新的问题
,
本地开发环境可以开启 --> 频繁修改代码的项目建议开启
生产环境建议开启 —>默认开启)