SpringCloudGateway+Consul集群部署笔记

spring cloud gateway已经使用了很长一段时间,一直有想法,整理整理一下,形成一个有效的记录笔记,近期抽空写成笔记。
1、基本环境
版本:consul-1.7.2
服务:192.168.11.45(windows)、192.168.110.35(centos72)、192.168.110.35(centos72)
2、安装目录
centos7.2:/opt/consul-1.7.2
windows:D:/test/consul
3、集群架构
1.三个consul服务节点,组成集群提供注服务
2.两个producer生产者服务,提供业务服务响应
3.一个gateway网关服务,提供路由转发服务
4.消费者模拟请求发送到网关,再由网关路由到生产者服务的业务中;
4、Consul
Consul是一个在分布式环境中的提供服务注册和发现流程的服务管理软件,分布式高可用,提供服务发现和配置共享,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。
在集群架构中,Consul保证了c(数据一致性)、a(高可用)特点,不保证p(分区容错)特点。在springCloud中已对Cloud进行了自动配置与封装,并且官方建议替代 Eureka。
Consul 采用 raft 算法来保证数据的强一致性:
a.服务注册到Consul时,raft协议要求必须过半数的节点都写入成功才认为注册成功;
b.集群中的Leader挂掉时,重新选举期间整个consul不可用,保证强一致性但会牺牲可用性。
安装过程比较简单,自行百度,省略...
4.1、集群配置
服务一:config/server1.json
{    "datacenter":"dc1",
    "node_name":"server1",
    "server":true,
    "data_dir":"/opt/consul-1.7.2/data",
    "addresses":{
        "http":"0.0.0.0"
    },
    "ports":{
        "http":8500,
        "serf_lan": 8301,
        "serf_wan": 8302
    }
}
服务二:config/server1.json(windows下使用)
{    "datacenter":"dc1",
    "node_name":"server2",
    "server":true,
    "data_dir":"D:/test/consul/data",
    "addresses":{
        "http":"0.0.0.0"
    },
    "ports":{
        "http":8500,
        "serf_lan": 8301,
        "serf_wan": 8302
    }
}
服务三:config/server1.json
{    "datacenter":"dc1",
    "node_name":"server1",
    "server":true,
    "data_dir":"/opt/consul-1.7.2/data",
    "addresses":{
        "http":"0.0.0.0"
    },
    "ports":{
        "http":8500,
        "serf_lan": 8301,
        "serf_wan": 8302
    }
}
4.2、启动服务
# linux
./consul agent -server -ui -bootstrap-expect=3 -config-file=./config/server1.json -advertise=192.168.110.35 -bind=0.0.0.0 -client=0.0.0.0# windwos
consul agent -server -ui -bootstrap-expect=3 -config-file=./config/server2.json -advertise=192.168.11.45 -bind=0.0.0.0 -client=0.0.0.0 -join 192.168.110.35# linux
./consul agent -server -ui -bootstrap-expect=3 -config-file=./config/server3.json -advertise=192.168.110.36 -bind=0.0.0.0 -client=0.0.0.0 -join 192.168.110.354.3、UI管理界面
URL: http://192.168.110.35:8500/ui
Nodes集群节点
3台服务启动正常,集群通讯成功;
4.4、查看集群状态
在任意一台consul节点所在的服务器上,输入:./consul operator raft list-peers
192.168.110.35为leader
192.168.11.45、192.168.110.35为follower
5、Spring Cloud Consul + Gateway
5.1、(微服务+网关)工程结构搭建
略.....
 注意SpringCloud和SpringBoot版本组合,否则会有兼容性或jar版本冲突: Spring-Cloud               Spring-Boot
 =================          ==============
 Hoxton.SR4                 2.2.6.RELEASE
 Hoxton.SR1                 2.2.1.RELEASE
 Greenwich.SR3              2.1.1.RELEASE
 Finchley.RELEASE           2.0.3.RELEASE
 本工程:
JVM:1.8
Spring-Cloud:Hoxton.SR1
Spring-Boot:2.2.1.RELEASE
5.2、建立生产者服务
consul-producer模块
pom.xml
<dependencies>    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
ProducerController.java
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
//生产者控制器
@RestController
@RequestMapping("/producer")
public class ProducerController {
    @Value("${server.port}")
    private String port;
    @RequestMapping(value = "/test")
    public String test() {
        return "test api server port: " + port + ",ok:" + System.currentTimeMillis();
    }
    @RequestMapping(value = "/test0")
    public String test0() {
        return "test0 api server port: " + port + ",ok:" + System.currentTimeMillis();
    }
    @RequestMapping(value = "/test1")
    public String test1() {
        return "test1 api server port: " + port + ",ok:" + System.currentTimeMillis();
    }
}
配置生产者服务一
application.yml
server:  port: 8086
  address: 0.0.0.0
  servlet:
    context-path: /
spring:
  application:
    name: consul-producer
  cloud:
    consul:
      host: 192.168.11.45
      port: 8500
      discovery:
        service-name: consul-producer
        hostname: 192.168.11.45
        tags: version=1.0,author=jianglong
management:
  health:
    refresh:
      enabled: true
服务端口:8086,注册到Consul服务节点IP为192.168.11.45
配置生产者服务二
application.yml
server:  port: 8087
  address: 0.0.0.0
  servlet:
    context-path: /
spring:
  application:
    name: consul-producer
  cloud:
    consul:
      host: 192.168.110.36
      port: 8500
      discovery:
        service-name: consul-producer
        hostname: 192.168.11.45
        tags: version=1.0,author=jianglong
management:
  health:
    refresh:
      enabled: true
服务端口:8086,注册到Consul服务节点IP为192.168.11.45
在idea中分二次启动consul-producer,每次按上述配置修改注册的consul节点host和port,表示启动两个相同服务名,但注册到不同consul节点的上的分布式生产者微服务;
5.3、建立网关服务
gateway-server模块
服务端口:8089,注册到Consul服务节点IP为192.168.110.35
pom.xml
<dependencies>    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
</dependencies>
application.yml
server:  port: 8089
  address: 0.0.0.0
  servlet:
    context-path: 
spring:
  application:
    # 服务名称
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          # 启用本地化网关
          enabled: true
          # 将服务名转换为小写
          lower-case-service-id: true
      # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters),filters 不是必需参数)
      routes:
      # id 必需唯一
      - id: consul-producer
        # lb:service-name 表示注册中心的服务名称
        uri: lb://consul-producer
        # 匹配条件
        predicates:
        # 路径断言匹配
        - Path=/producer/**
        # 必需是POST请求
        - Method=POST
        filters:
        # 在转发url后加参数name=jiang
        - AddRequestParameter=name,jiang
#          - StripPrefix=1
#           - Cookie=mycookie,mycookievalue
      - id: test0-id
        # 转发到指定url
        uri: http://192.168.11.45:8086
        predicates:
        # 路径断言匹配
        - Path=/route/producer/test0
        filters:
        # StripPrefix=1表示过滤Path第一段(截取/test)
        - StripPrefix=1
        # 在转发url后加参数version=test0
        - AddRequestParameter=version,test0
        # 添加熔断机制,当服务不可用时或超过了指定超时长,则转发到fallback
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/fallback
      - id: test1-id
        # 转发到指定url
        uri: http://192.168.11.45:8087
        predicates:
        - Method=GET
        # 路径断言匹配
        - Path=/route/producer/test1
        filters:
        # StripPrefix=1表示过滤Path第一段(截取/test)
        - StripPrefix=1
        # 在转发url后加参数version=test1
        - AddRequestParameter=version,test1
        # 添加熔断机制,当服务不可用时或超过了指定超时长,则转发到fallback
        - name: Hystrix
          args:
            name: test1Hystrix
            fallbackUri: forward:/fallback/test1
    # consul注册中心
    consul:
      # 注册中心host
      host: 192.168.110.35
      # 注册中心端口
      port: 8500
      # 服务配置
      discovery:
        # 注册到consul的服务名称
        service-name: ${spring.application.name}
        # 注册到consul的hostname(主机名称,consul是通过hostname提供给客户端连接的)
        hostname: 192.168.11.45
        # 注册到consul的标识
        tags: version=1.0,author=jianglong
        ip-address: 192.168.11.45
# 启用服务健康检测,consul将通过http://host:port/actuator/health 检测服务的存活,默认10s一次
management:
  health:
    refresh:
      enabled: true
# 配置日志
logging:
  level:
    # log 级别
    org.springframework.cloud.gateway: debug
# 熔断器配置
hystrix:
  command:
    default:
      execution:
        timeout:
          # enabled表示是否启用超时检测,默认为true
          enabled: true
        isolation:
          thread:
            # 全局熔断器超时
            timeoutInMilliseconds: 5000
    # test1Hystrix为熔断器名称,对应:filters.args.name
    test1Hystrix:
      execution:
        timeout:
          # enabled表示是否启用超时检测,默认为true
          enabled: false
        isolation:
          thread:
            # 特定服务熔断器超时
            timeoutInMilliseconds: 2000
GatewayController.java(熔断测试控制器)
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;
//熔断机制测试控制器
@RestController
@RequestMapping("/fallback")
public class GatewayController {
    @RequestMapping("")
    public String fallback(){
        return "error fallback method , " + System.currentTimeMillis();
    }
    @RequestMapping("/test1")
    public String fallbackTest1(){
        return "error fallbackTest1 method , " + System.currentTimeMillis();
    }
}
以上三个服务均在开发机器:192.168.11.45上
6、服务检测
consul集群成功、微服务注册成功
consul-producer 成功注册了两个微服务
gateway-service 成功注册了一个微服务
7、发起网关请求
192.168.11.45:8089为网关服务IP+端口
7.1、测试网关test0接口
http://192.168.11.45:8089/route/producer/test0
按照网关服务application.yml配置,route/producer/test0转发接口指向微服务:192.168.11.45:8086
7.2、测试网关test1接口
http://192.168.11.45:8089/route/producer/test01
按照网关服务application.yml配置,route/producer/test1转发接口指向微服务:192.168.11.45:8087
8、熔断测试
把gateway-service模块的
application.yml中,是否启用超时检测enabled
设置为true,并且超时时间设为2000毫秒(2秒钟)
test1Hystrix 指向的网关配置中的- id: test1-id下的args.name: test1Hystrix
# test1Hystrix为熔断器名称,对应:filters.args.nametest1Hystrix:
  execution:
    timeout:
      # enabled表示是否启用超时检测,默认为true
      enabled: false
    isolation:
      thread:
        # 特定服务熔断器超时
        timeoutInMilliseconds: 2000
修改完毕,重启网关服务
在生产者模块的ProducerController.java中对test1()方法进行修改,加入一行代码:Thread.sleep(7 * 1000);对网关转发进入该test1()方法时暂停7秒。
重新发起test1网关测试
http://192.168.11.45:8089/route/producer/test1
因网关中的超时设置为timeoutInMilliseconds: 2000,而生产者服务中的暂停时长为1000*7毫秒,在请求转发到达test1后,因超时网关会触发熔断机制,会转发到“fallbackUri: forward:/fallback/test1”网关内的回调fallbackTest1()方法中,返回上述内容;
9、Consul故障测试
测试consul在集群的情况下,出现宕机或故障,导致节点或服务不可用的情况下的表现;
9.1、网关转发与consul注册规则
http://192.168.11.45:8089/route/producer/test0
按照网关服务application.yml配置,route/producer/test0转发接口指向微服务:192.168.11.45:8086
192.168.11.45:8086服务注册在consul集群的server2
http://192.168.11.45:8089/route/producer/test1
按照网关服务application.yml配置,route/producer/test1转发接口指向微服务:192.168.11.45:8087
192.168.11.45:8087服务注册在consul集群的server3
9.2、停止集群服务server3
模拟服务宕机,手动在服务器上kill掉server3,模拟服务进程异常,服务宕机;
关掉server3,查找IP192.168.110.36所在服务上的进程,kill掉
ps -ef|grep consul
kill -9 pid
没有server3节点的显示
项目模块consul-producer生产者2
生产者2服务信息
192.168.11.45:8087,注册到consul集群中的server3(IP:192.168.110.36)
日志中抛异常“org.apache.http.conn.HttpHostConnectException: Connect to 192.168.110.36:8500 [/192.168.110.36] failed: Connection refused: connect”
重新发起test1网关测试
http://192.168.11.45:8089/route/producer/test1
按照网关服务application.yml配置,route/producer/test1转发接口指向微服务:192.168.11.45:8087
9.3、通过服务名称转发
变更配置,将gateway模块下的application.yml中test0-id和test1-id的uri路径更改为lb://consul注册服务名
test0-id
- id: test0-id  # 转发到指定url
  # uri: http://192.168.11.45:8086
  uri: lb://consul-producer
test1-id
- id: test1-id  # 转发到指定url
  # uri: http://192.168.11.45:8087
  uri: lb://consul-producer
重新发起test1网关测试
http://192.168.11.45:8089/route/producer/test1
按照网关服务application.yml配置,route/producer/test1转发接口指向微服务:lb://consul-producer
由于consul集群中的server3已下线,192.168.11.45:8087注册微服务无效,则直接转发到了同名服务,192.168.11.45:8086下
9.4、停止集群服务server2
模拟服务宕机,我们继续停掉server2,只保留集群server1主服务节点(leader)
手动在服务器上kill掉server2,模拟服务进程异常,服务宕机;
因为server2是部署在本地开发机器上,是windows环境,直接在cmd命令窗口ctrl + c即可;
在刷新consul的UI管理界面,则出现500错误
集群中存活的server1节点(原集群中的leader),后端有抛“No cluster leader”,提示没有集群领导者。原因是和consul节点过半宕机,服务无法选举leader节点;
再一次刷新test1网关接口,转发正常
http://192.168.11.45:8089/route/producer/test1
此时除server1节点外,其它server2、server3节点服务发现与注册中心因空宕机均不可用,并且server1不在是leader节点;
9.5、停止集群服务server1
模拟服务宕机,我们继续停掉server1,整个集群服务中的所有consul节点全部停止不可用;
手动在服务器上kill掉server1,模拟服务进程异常,服务宕机;
刷新UI界面,此时看到server2还在,这是consul的数据缓存,实际server2服务已停止
关掉server1,查找IP192.168.110.35所在服务上的进程,kill掉
ps -ef|grep consul
kill -9 pid
再次刷新
http://192.168.110.35:8500/ui/,已变成无法访问网站,因为server1所对应的节点为192.168.110.35已停止服务;
项目模块gateway-server网关服务
网关服务信息
192.168.11.45:8089,注册到consul集群中的server1(IP:192.168.110.35)
日志中抛异常“org.apache.http.conn.HttpHostConnectException: Connect to 192.168.110.35:8500 [/192.168.110.35] failed: Connection refused: connect”
虽然网关注册的consul服务节点因宕机不可用,但再一次刷新test1网关接口,转发是正常的
http://192.168.11.45:8089/route/producer/test1
经过上述测试,从关闭server3节点、再关闭server2节点,到最后关闭server1节点的所有节点,网关转发始终是正常的;
由于SpringCloudGateway网关会从consul中拉取一份已注册的微服务清单,同时会本地也会维护一套路由配置规则,当consul服务副节点下线后,网关还是从注册的consul节点后获取同名服务尝试连接,如果连接成功则断续转发;如果网关注册的consul节点停止服务不可用,则SpringCloudGateway会从本地维护的SpringCloudConsul微服务清单和网关规则中匹配合适的微服务,继续提供网关转发服务;
10、恢复consul集群
参考前面的,启动服务章节,启动server1、server2、server3,启动过程不需要按顺序启动,但要保证-join 192.168.110.35,先一步启动,以免其它节点加入集群时,找不到节点;
服务全部启动完毕后,3个节点选举server1为leader主节点,其它server2 、server3均为follower为追随节点;
10.1、项目模块恢复
server1、server2、server3三个节点恢复正常集群后,两个conusl-producer生产者服务和gateway-server网关服务均无继续抛错,日志恢复正常,整个consul集群+springcloud分布式微服务架构继续提供业务高可用性服务;
10.2、网关变更注册节点
更改gateway-server模块的appclication.yml配置,把consul.host从192.168.110.35(leader)修改为192.168.110.36(follwer),将网关从注册leader节点变更到注册follwer节点;
# consul注册中心consul:
  # 注册中心host
  # host: 192.168.110.35
  host: 192.168.110.36
重启gateway-server网关服务,成功注册到server3节点
再一次刷新test1网关接口,转发正常
http://192.168.11.45:8089/route/producer/test1
通过上述变更网关注册的consul节点,测试验证微服务可以通过当前consul注册节点,查询集群内其它consul节点微服务注册信息;
11、总结:
1.consul集群中,数据中心的leader节点是负责所有follower的数据同步和通讯;微服务可以通过当前注册consul节点(leader和follwer),查询consul集群中其它节点注册的微服务信息;
2.gateway网关应用模块,注册到leader节点,从leader节点中,拉取了consul集群中其它follower节点内注册的微服务清单;
3.consul集群中任意节点的退出或故障,会导制注册的到该consul节点的微服务抛异常,极端下甚至服务不可用;同时新的微服务是无法注册到宕机consul节点上;
4.当整个consul集群不可用时,gateway网关服务,会从自身从consul拉取的微服务清单和自身维护的一套路由规则中去匹配转发接口到指定微服务中;
5.当整个consul集群服务恢复正常时,基于SpringCloudConsul的微服务会自动连接到consul集群中各自注册的节点上,恢复正常业务架构;
参考:
https://cloud.spring.io/spring-cloud-static/spring-cloud-consul/2.2.2.RELEASE/reference/html/#spring-cloud-consul-agent
© 著作权归作者所有
打赏
点赞 (0)
收藏 (0)
分享
微博
微信
打印
举报
上一篇:
用100多行python代码开发java代码生成器
下一篇:
JAVA造轮子之-zookeeper节点操作工具类
不
不会飞的小龙人
开源项目作者
作为一个开源项目作者,是时候站出来拯救世界了!
领取时间:2020/08/03
领取条件:开源项目被开源中国收录的开发者可领取
合格公民
每次投票都是发自真心!
领取时间:2019/08/28
领取条件:第一次对回答或提问投票(顶)
Gitee 达人
我的开源软件已入驻码云 Gitee,快来看看吧!
领取时间:2020/08/03
领取条件:开源软件使用码云 Gitee 源码地址
粉丝 3
博文 26
码字总数 34091
作品 1
武汉
关注
私信
提问
加载中
请先登录后再评论。
删除一条评论
评论删除后,数据将无法恢复
取消
确定
相关文章
最新文章
我的架构演化笔记 功能1: 基本的用户注册
“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...
强子哥哥
2014/05/31
976
3
CDH5: 使用parcels配置lzo
一、Parcel 部署步骤 1 下载: 首先需要下载 Parcel。下载完成后,Parcel 将驻留在 Cloudera Manager 主机的本地目录中。 2 分配: Parcel 下载后,将分配到群集中的所有主机上并解压缩。 3 激...
cloud-coder
2014/07/01
6.8K
1
Nutch学习笔记4-Nutch 1.7 的 索引篇 ElasticSearch
上一篇讲解了爬取和分析的流程,很重要的收获就是: 解析过程中,会根据页面的ContentType获得一系列的注册解析器, 依次调用每个解析器,当其中一个解析成功后就返回,否则继续执行下一个解...
强子哥哥
2014/06/26
712
0
桌面即时贴软件--GloboNote
GloboNote 是一个桌面记事软件,可帮你创建待办事宜、提醒和其他笔记信息。无限制即时贴的数量,可分组整理,支持搜索,可定制文本的显示格式(字体、颜色和大小),可将某个即时贴始终显示在...
匿名
2013/01/21
6.8K
1
集群存储系统--YFS
YFS集群存储系统由多个元数据服务器(MDS)、多个块数据服务器(CDS)和多个客户端(client)互联组成集群; 数据被分成64M固定大小的数据块(Chunk),每个数据块在CDS本地以常规文件的形式...
匿名
2013/02/19
1.8K
0
没有更多内容
加载失败,请刷新页面
加载更多
下一页
CSS基本选择器
标签选择器 HTML标签作为标签选择器的名称<h1>…<h6>、<p>、<img/> 类选择器 一些特殊的实现效果,单纯使用标签选择器不能实现,从而引出类选择器 ID选择器 ID选择器的名称就是HTML中标签的...
hmyqwe
刚刚
0
0
SpringCloudGateway+Consul集群部署笔记
spring cloud gateway已经使用了很长一段时间,一直有想法,整理整理一下,形成一个有效的记录笔记,近期抽空写成笔记。 1、基本环境 版本:consul-1.7.2 服务:192.168.11.45(windows)、1...
不会飞的小龙人
刚刚
0
0
搞工程和搞电子的人摆摊能做什么?
由于疫情的影响 国家开始鼓励地摊经济。 我们来看看,搞工程和搞电子的人摆摊能什么。 先看,搞工程的人是这样摆摊的! 而搞电子的人是这样摆摊的! PCB工程师 测试工程师 射频工程师 单片机...
IT技术分享社区
07/08
0
0
三年级小孩子的解题思路
专业术语这叫对称性残缺,对三年级小孩子讲,就叫镜子! 有时懂了并不一定能让别人也很好的懂得...... 做一个好老师,其实真的很难, 太难了! 无数伟大的科学家、艺术家都不是好的老师! 本...
mathwater
05/07
0
0
每日一讲11:兔子繁殖推算
题目:古 典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 程序分析:兔子的规律为数列1...
花儿开放
07/27
0
0
没有更多内容
加载失败,请刷新页面
加载更多
下一页
OSCHINA 社区
关于我们
联系我们
合作伙伴
Open API
在线工具
码云 Gitee.com
企业研发管理
CopyCat-代码克隆检测
实用在线工具
微信公众号
OSCHINA APP
聚合全网技术文章,根据你的阅读喜好进行个性推荐
下载 APP
©OSCHINA(OSChina.NET)
工信部
开源软件推进联盟
指定官方社区
深圳市奥思网络科技有限公司版权所有
粤ICP备12009483号
顶部
以上是 SpringCloudGateway+Consul集群部署笔记 的全部内容, 来源链接: utcz.com/z/519281.html

