环境 | 版本 |
---|---|
Springboot | 2.1.5.RELEASE |
Springcloud | Greenwich.SR1 |
jdk | 1.8 |
Maven私服 | 第二篇搭建的私服 |
腾讯云系统 | centos7 |
腾讯云ip | 192.168.1.100(非真实ip) |
相信许多朋友或多或少都使用或接触过Springcloud。Springcloud基于Springboot开发,提供了一套完整的微服务解决方案,其丰富的组件,配置中心,全链路监控,API网关,熔断器等选型中立的开源组件,可以按需扩展和替换。今天做为Springcloud系列第一篇,就从环境搭建开始,后续章节也都会在此环境下进行书写。
1.大版本命名:Springcloud版本命名以伦敦地铁站名称英文字母升序排列。
2.小版本命名:同一大版本中会有许多不同的小版本,小版本以".SRX"的命名格式,其中"X"为数字,如Greenwich.SR1
Springcloud的版本需与Springboot版本选择相匹配,否则启动时会报错且无法启动成功,版本对应如下表,大家也可以登录Springcloud官网进行查阅springcloud与springboot版本对比
Springcloud版本 | Springboot版本 |
---|---|
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
Greenwich.SR1
,Springboot版本为2.1.5.RELEASE
,下边开始我们Springcloud项目的搭建,搭建maven工程比较简单,在此就不做演示,下边只展示项目pom.xml。1.引入Springboot父级依赖
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.5.RELEASEversion>
parent>
2.设置变量
<properties>
<jdk.version>1.8jdk.version>
<spring.cloud.version>Greenwich.SR1spring.cloud.version>
properties>
3.引入Springcloud依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring.cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
4.完整pom.xml依赖
<properties>
<jdk.version>1.8jdk.version>
<spring.cloud.version>Greenwich.SR1spring.cloud.version>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.5.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring.cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<encoding>utf-8encoding>
<source>${jdk.version}source>
<target>${jdk.version}target>
configuration>
plugin>
plugins>
build>
上述依赖配置完毕后,等待下载依赖jar包,本系列文章的依赖都是从上一篇文章搭建的Maven私服下载的,大家也可以配置阿里云镜像或直接从中央仓库下载,依赖下载时间看自己网速,静待依赖下载完成,咱们的Springcloud项目环境准备已经完成,那就开始注册中心的学习吧。
1.Eureka闭源,相信大家都知道Eureka2.0版本已经闭源了,1.x版本可正常使用,2.x已经开源部份可以正常使用,但风险自担,大家可以看看官方说明Eureka闭源wiki
2.在此还想讲讲Eureak,主要是想保证文章的完整性,下边我们会整合Springcloud+consul做为后续文章的注册中心
注册中心见名知意,就是专门用来注册服务之用。在微服务中,服务提供者将服务注册至注册中心,服务消费者要调用某个服务,则从注册中心查找需要调用的服务ip:port,然后本地通过http调用服务,从而完成服务调用。
(1) 引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
dependencies>
(2) 书写application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
参数名 | 说明 |
---|---|
eureka.instance.hostname | eureka服务端ip |
eureka.client.fetch-registry | 是否获取注册表信息,由于是服务Eureka server,则设置为false |
eureka.client.register-with-erueka | 是否将服务注册至注册中心 |
eureka.client.service-url: | 注册中心地址 |
(3) 书写启动类,注册中心添加@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
(4) 启动服务,访问http://localhost:8761/
,出现如下图所示,即表示注册中心配置成功
(1) 引入依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
(2) 书写application.yml
server:
port: 8762
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: eureka-client
(3) 书写启动类,添加@EnableEurekaClient
注解
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
(4) 查看服务是否注册至注册中心,输入http://localhost:8761
,出现下图表示服务已经注册至注册中心
注意:Eureka使用LeaseInfo来标识服务租约信息,其包含如下说明,通过其默认值可看出,虽然有时候服务已经停止了,但是在注册中心中还是能看到该服务在线
字段 | 说明 | 默认值 |
---|---|---|
renewalIntervalInSecs | Client端续约的间隔周期 | 30s |
durationInSecs | Client端需要设定的租约效时长 | 90s |
registrationTimestamp | Server端设置的该租约第一次注册时间 | |
lastRenewalTimestamp | Server端设置的该租约最后一次续约时间 | |
evictionTimestamp | Server端设置的该租约被剔除时间 | |
serviceUpTimestamp | Server端设置的该服务实例标记为up的时间 |
Register-服务注册
当Eureka Client向Eureka Server注册时,Eureka Client提供自身元数据,比如ip地址、端口、运行状况指标等
Renew-服务续约
(1) Eureka Client默认情况下每隔30秒发送一次心跳来进行服务续约
(2) Eureka Server在90秒内没收到Eureka Client心跳,则视为客户端服务不可用,Eureka Server会将Eureka Client实例从注册列表中删除
Fetch Registries-获取服务注册列表信息
(1) Eureka Client从Eureka Server获取服务注册信息,并将其缓存在本地.Eureka Client会使用服务注册列表信息查找其它服务信息,从而进行远程调用
(2) 缓存在本地的服务注册列表定时(每30秒)更新一次,每次返回注册列表信息可能与Eureka Client缓存信息不同,Eureka Client会自己处理这些信息
Cancel-服务下线
(1) Eureka Client在程序关闭时可以向Eureka Server发送下线请求,该客户端的实例信息将从Eureka Server服务注册列表中删除
(2)该下线请求不会自动完成,需在程序中关闭时调用以下代码
DiscoveryManager.getInstance().shutdownComponet
Eviction-服务剔除
默认情况下,当Eureka Client连续90秒没有向Eureka Server发送服务续约时,Eureka Server会将该实例从服务注册列表剔除
由于Eureka2.0已经闭源,官方只支持开源部份Eureka2.x,且使用效果不做保证,故在此介绍Springcloud整合consul作为注册中心,大家不了解Consul的,可以先上Consul官网了解。在Springcloud官网中将Springcloud consul与其它Springcloud组件并列,可见consul已经得到Spring认可并推荐,刚好在平时工作中使用的是Consul作为注册中心,因此在此给大家讲介绍下Springcloud整合consul
注意:由于Consul动西必较多,且本次整合不涉及深入了解,所以许多理论动西在此省略,大家有兴趣的可以自行去官网查看,在此只讲解Springcloud如何整合Consul,Consul配置说明
1.下图为Consul官方文档图,该图展示了Consul结构,有多个数据中心(DataCenter),每个DataCenter中又包括许多节点信息,分别为Client和Server,其中所有Server中有一个Leader。
2.Clent端负责接受连接请求,但不做持久化数据操作
3.Server端会持久化数据,其它功能与Client端作用类似
4.Server Leader负责数据同步
Docker安装consul可以参考Docker hub介绍Consul安装,但感觉写得很模糊,有兴趣的童鞋可以看看
# 拉取镜像
$ docker pull consul
端口 | 说明 |
---|---|
8500 | 用户客户端请求端口 |
8600 | 解析DNS查询 |
8300 | server间通信端口 |
8301 | Serf LAN端口 |
8302 | Serf WAN端口 |
2.consul参数说明
参数 | 说明 |
---|---|
-server | 表示该节点为server节点,如果不加则默认为client节点 |
-bootstrap-expect | 表示期望有几个节点,设置为3,该集群未达到3个则该注册中心无法工作 |
-node | 表示给启动节点设置别名 |
-datacenter | 表示给数据中心命名,后续节点要加入该集群,都需设置为相同数据中心名,否则会启动失败 |
-ui | 表示启动ui界面,可通过浏览器访问 |
-bind | 设置为0.0.0.0表示对任意主机开放 |
-client | 与bind功能类似,其默认值为127.0.0.1 |
$ docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 dfe3bf9e6fe6 agent -server -bootstrap-expect 3 -node=n1 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0
$ docker inspect --format ‘{{ .NetworkSettings.IPAddress }}‘ consul1
-join:后边跟要加入的服务节点ip
$ docker run --name consul2 -d -p 8600:8500 dfe3bf9e6fe6 agent -client -node=n2 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.3
$ docker run --name consul3 -d -p 8700:8500 dfe3bf9e6fe6 agent -client -node=n3 -datacenter=st1 -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.3
1.上述启动成功后,浏览器键入
http://192.168.1.100:8500
(ip填写自己电脑ip)出现如下界面表示Consul安装并启动成功
2.st1:表示上述设置的数据中心名
3.n1、n2、n3:表示节点名,也是上边启动时设置参数
经过上边步骤,我们的docker环境已经安装上Consul并且启动成功,下边我们继续将consul整合至上边我们搭建的环境中
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-consul-allartifactId>
dependency>
上边依赖为组合依赖,其实上边依赖等同于下边三个依赖,大家使用工具可以看到,大家选择上边依赖或下边依赖均可
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-consul-busartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-consul-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-consul-discoveryartifactId>
dependency>
dependencies>
在项目的resource目录新建一配置文件,取名为
bootstrap.yml
,这儿涉及至springboot启动时配置文件加载顺序问题,这儿就不作过多说明,配置文件如下
spring:
application:
# 服务注册名
name: order-service
cloud:
consul:
config:
# 设置配置文件夹
prefix: config
# 设置配置文件夹位置
default-context: application
# 设置配置文件名称
data-key: data
# 设置配置文件显示样式,有properties和yaml两种格式
format: yaml
# 开启监听,动态刷新配置,默认每秒触发一次
watch:
enabled: true
# 修改动态刷新配置时间
# delay: 2000
# 应用和profile之间的分割符,与spring.profiles.active配合使用
# profile-separator: ,
enabled: true
# consul服务器地址
host: 192.168.1.100
# 默认端口号
port: 8500
# 是否注册,默认为true
discovery:
register: true
# 健康检查时间
health-check-timeout: 2m
enabled: true
heartbeat:
enabled: true
# 优先ip注册
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.hostname}:${spring.application.instance_id:${server.port}}
参数说明:
参数名 | 说明 | 说明或默认值 |
---|---|---|
spring.loud.config.prefix | 配置文件夹前缀名 | config |
spring.loud.config.default-context | 配置文件夹位置 | application |
spring.loud.config.data-key | 配置文件名称 | data |
spring.loud.config.format | 配置文件以何种方式展 | 默认key_valu,还有properties、yaml、files |
spring.loud.config.watch.enable | 开启监听动态刷新配置 | true |
spring.loud.config.watch.delay | 动态刷新配置时间 | 1000 |
spring.loud.config.enabld | 允许配置 | true |
spring.loud.config.host | 注册中心ip | localhost |
spring.loud.config.port | 注册中心i端口 | 8500 |
spring.loud.config.discovery.register | 是否将服务注册至注册中心 | true |
spring.loud.config.discovery.health-check-timeout | 心跳检测超时时间 | |
spring.loud.config.discovery.enabled | 允许服务被发现 | |
spring.loud.config.discovery.heartbeat.enabled | 允许服务心跳检测 | |
spring.loud.config.discovery.prefer-ip-address | 优先ip注册 | false |
spring.loud.config.discovery.instance-id | 唯一的实例id,即服务注册id |
注意:spring.loud.config.discovery.heartbeat.enabled在配置时一定要配置,在实验中,未配置时服务能注册进注册中心但心跳检测始终失败,导致服务不可用,如下图所示为服务不可用状态
@EnableDiscoveryClient表示允许服务被发现,启动时必须添加该注解
@SpringBootApplication
@EnableDiscoveryClient
@RefreshScope
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class, args);
}
}
1.配置成功后,浏览器键入
http://192.168.1.100:8500
出现下图,表示配置成功
2.能看到已经注册上的两个服务分别时order-service
和user-service
3.在health checks处无错误,表示服务注册及心跳检测正常
1.在团队中经常会遇到注册至注册中心,从页遭成消费消息等情况发生,可通过postman或其它方式剔出服务
2.服务instanceId即为bootstrap.yml文件配置的spring.cloud.consul.discovery.instanceId
参数
$ put http://192.168.1.100:8500/v1/agent/service/deregister/服务instanceId
config
,config
为项目配置文件中spring.loud.config.prefix
配置参数/
结尾,配置文件名为服务名data-key
配置的名称注意:该处配置会覆盖项目中的application.yml文件,因此如果公有属性可设置在此处