注意: 因为涉及到配置测试切换, 中间环节需按此文章操作体验, 代码仓库里面的只有最后一步的代码

准备好了微服务, 那我们就来看看网关+负载均衡如何一起工作

新建一个模块hello-gateway, 开启gateway和loadbalancer, pom部分如下:

<?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.cnscud.betazone</groupId>
<artifactId>betazone-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <artifactId>hello-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-gateway</name>
<description>Demo project for Spring Boot</description> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</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-loadbalancer</artifactId>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

HelloGatewayApplication 不修改, 使用默认的实现.

下面我们来实验几种配置, 看看LoadBalancer的表现

1. 默认配置, 不配置zone: application.yml (没有CustomLoadBalancerConfiguration标注)

server:
port: 8800 spring:
application:
name: betazone-hello-gateway
main:
allow-bean-definition-overriding: true
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
routes:
- id: remotename
uri: lb://betazone-hello-remotename
predicates:
- Path=/remoteapi/**
filters:
- StripPrefix=1
loadbalancer:
ribbon:
enabled: false eureka:
instance:
prefer-ip-address: true client:
register-with-eureka: true
fetch-registry: true
prefer-same-zone-eureka: true
service-url:
defaultZone: http://localhost:8001/eureka/ logging:
level:
org.springframework.cloud: debug

启动应用, 访问 http://localhost:8800/remoteapi/remote/id/2, 刷新几次浏览器, 可以看到内容在

"World [remotename: 127.0.0.1:9001]"
"World [remotename: 127.0.0.1:9002]"

两种情况下依次切换, 说明LoadBalancer在生效, 但是没有任何zone设置.

2. 实验: 设置应用的metadata的zone, 负载均衡会不会自动感知哪?

我们复制一份application-main.yml, 修改如下:

server:
port: 8801 spring:
application:
name: betazone-hello-gateway
main:
allow-bean-definition-overriding: true
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
routes:
- id: remotename
uri: lb://betazone-hello-remotename
predicates:
- Path=/remoteapi/**
filters:
- StripPrefix=1
loadbalancer:
ribbon:
enabled: false eureka:
instance:
prefer-ip-address: true
metadata-map:
zone: main
client:
register-with-eureka: true
fetch-registry: true
prefer-same-zone-eureka: true
service-url:
defaultZone: http://localhost:8001/eureka/ logging:
level:
org.springframework.cloud: debug

修改了eureka.instance.metadata-map.zone 为main, 端口改为8801, 按此配置启动应用, 访问 http://localhost:8801/remoteapi/remote/id/2

发现和第一种情况一样, zone没有生效, 说明默认的LoadBalancer没有考虑zone配置.

3. 开启LoadBalancer的zone感应 (main区域)

修改application-main.yml中loadbalancer部分如下:

spring:
cloud:
loadbalancer:
ribbon:
enabled: false
zone: main
configurations: zone-preference

重新运行, 访问 http://localhost:8801/remoteapi/remote/id/2

现在生效了, 服务总是返回 "World [remotename: 127.0.0.1:9001]" , 不再返回端口 9002的信息了, 说明 zone区域设置生效了.

设置关键点:

  • zone 设置loadbalancer要访问的服务的zone, 如果没设置, 则按需读取实例的eureka.instance.metadata-map.zone设置
  • configurations 具体描述看Spring文档, 此处zone-preference 则设置优先按区域选择服务实例.

4. 测试LoadBalancer的zone感应 (beta区域)

复制一份application-beta.yml, 修改端口为 8802, 相关的zone都改为beta区域,
修改application-main.yml中loadbalancer部分如下:

server:
port: 8802 spring:
cloud:
loadbalancer:
ribbon:
enabled: false
zone: beta
configurations: zone-preference

复制配置, 修改profile为beta, 启动实例, 访问 http://localhost:8802/remoteapi/remote/id/2, 则可以看到总是输出 "World [remotename: 127.0.0.1:9002]", 说明beta区域设置生效了.

此时我们可以看到如何使用内置的 "zone-preference"了, 那么我们如何自己定义个性化的策略哪, 我们可以看到Spring的这个配置指向 LoadBalancerClientConfiguration, 打开源码,
可以看到里面有好多的discoveryClientServiceInstanceListSupplier实现, 我们自己实现(抄袭)一个不就可以了吗?

5. 定制ServiceInstanceListSupplier

我们先直接抄袭一份出来, 作为我们自己的实现(个性化实现代码不同, 但是流程一样, 这里主要跑通流程)

/**
* 自定义 Instance List Supplier: 根据默认Zone划分.
* 也可以自己实现zone规则
*
*/
public class CustomLoadBalancerConfiguration { @Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withZonePreference()
.withCaching()
.build(context);
} }

这里直接就是从 zonePreferenceDiscoveryClientServiceInstanceListSupplier 抄袭过来的, 我们主要先演示一下流程, 后面我们会实现自己的ServiceInstanceListSupplier.

声明配置以便生效:

@Configuration(proxyBeanMethods = false)
@LoadBalancerClients(defaultConfiguration = CustomLoadBalancerConfiguration.class)
public class SamezoneAutoConfiguration {
}

注释掉yml里面的 configurations: zone-preference, 其他不修改, 重新启动8801, 8802端口, 重新测试.

效果和上面一样, 说明通过类的方式也同样效果, 只不过我们可以使用自己定制的ServiceInstanceListSupplier 了.

  • 注意:
    zone设置优先以 eureka.instance.metadata-map.zone 为首要设置, 没有特殊情况下不要设置spring.cloud.loadbalancer.zone, 这样loadbalancer就会读取实例的zone.

代码位置: https://github.com/cnscud/javaroom/tree/main/betazone2/hello-gateway 注意代码只是最后一步的情况

接下来我们实验一下连锁调用的情况下, zone配置会不会被继承传递哪? 什么情况下会失效哪? ......

Spring Cloud分区发布实践(3) 网关和负载均衡的更多相关文章

  1. Spring Cloud分区发布实践(1) 环境准备

    最近研究了一下Spring Cloud里面的灰度发布, 看到各种各样的使用方式, 真是纷繁复杂, 眼花缭乱, 不同的场景需要不同的解决思路. 那我们也来实践一下最简单的场景: 区域划分: 服务分为be ...

  2. Spring Cloud分区发布实践(6)--灰度服务-根据Header选择实例区域

    此文是一个完整的例子, 包含可运行起来的源码. 此例子包含以下部分: 网关层实现自定义LoadBalancer, 根据Header选取实例 服务中的Feign使用拦截器, 读取Header Feign ...

  3. Spring Cloud分区发布实践(4) FeignClient

    上面看到直接通过网关访问微服务是可以实现按区域调用的, 那么微服务之间调用是否也能按区域划分哪? 下面我们使用FeignClient来调用微服务, 就可以配合LoadBalancer实现按区域调用. ...

  4. Spring Cloud分区发布实践(5)--定制ServiceInstanceListSupplier

    现在我们简单地来定制二个 ServiceInstanceListSupplier, 都是zone-preference的变种. 为了方便, 我重新调整了一下项目的结构, 把一些公用的类移动到hello ...

  5. Spring Cloud分区发布实践(2) 微服务

    我们准备一下用于查询姓名的微服务. 首先定义一下服务的接口, 新建一个空的Maven模块hello-remotename-core, 里面新建一个类: public interface RemoteN ...

  6. Spring Cloud微服务开发笔记5——Ribbon负载均衡策略规则定制

    上一篇文章单独介绍了Ribbon框架的使用,及其如何实现客户端对服务访问的负载均衡,但只是单独从Ribbon框架实现,没有涉及spring cloud.本文着力介绍Ribbon的负载均衡机制,下一篇文 ...

  7. Spring cloud gateway 如何在路由时进行负载均衡

    本文为博主原创,转载请注明出处: 1.spring cloud gateway 配置路由 在网关模块的配置文件中配置路由: spring: cloud: gateway: routes: - id: ...

  8. spring boot 2.0.3+spring cloud (Finchley)2、搭建负载均衡Ribbon (Eureka+Ribbon+RestTemplate)

    Ribbon是Netflix公司开源的一个负载均衡组件,将负载均衡逻辑封装在客户端中,运行在客户端的进程里. 本例子是在搭建好eureka的基础上进行的,可参考spring boot 2.0.3+sp ...

  9. spring cloud学习(三)使用Ribbon实现客户端负载均衡

    使用Ribbon实现客户端的负载均衡 * 个人博客空间 : https://zggdczfr.cn/ * Ribbon Spring Cloud Netflix Ribbon 是一个客户端负载均衡的组 ...

随机推荐

  1. Windows操作系统添加永久静态路由

    1.比如:添加一条去往 10.10.10.0/24网段的静态路由,指定去往此网段的路由都走 172.20.153.254网关 route -p add 10.10.10.0 mask 255.255. ...

  2. Unity3D学习笔记1——绘制一个三角形

    目录 1. 绪论 2. 概述 3. 详论 3.1. 准备 3.2. 实现 3.3. 解析 3.3.1. 场景树对象 3.3.2. 绘制方法 4. 结果 1. 绪论 最近想学习一下Unity3d,无奈发 ...

  3. 『无为则无心』Python序列 — 18、Python列表概念及常用操作API

    目录 1.列表的概念 (1)列表的定义 (2)列表的应用场景 (3)列表的定义格式 2.列表的常用操作 (1)列表的查找 1)通过下标查找 2)通过方法查找 3)判断是否存在 (2)列表的增加 @1. ...

  4. zbxtable的使用

    实验环境: zabbix server 172.16.1.121 mysql 172.16.1.121 访问端 172.16.1.122 54.1 zbxtable 1 说明 ZbxTable使用Go ...

  5. 7、Oracle通过客户端(sqlplus)登录认证用户的方式

    select version from v$instance; #查看当前数据库的版本 192.168.31.5:1521/orcl 7.1.操作系统认证: 1.Oracle认为操作系统用户是可靠的, ...

  6. js 判断是什么浏览器加载页面

    一.Navigator 属性: 1)appcodeName  返回浏览器代码名 2)appminorVersion  返回浏览器次级版本 3)appname  返回浏览器名称 4)browserLan ...

  7. ubuntu docker开启2375端口,支持远程访问

    1.编辑docker文件:/usr/lib/systemd/system/docker.service vi /usr/lib/systemd/system/docker.service 2.Exec ...

  8. [小技巧] Windows7 半角全角快捷键 修改方法

    From : http://blog.sina.com.cn/s/blog_87ab67b10100x3ww.html 转载说明:在浏览器下我们可以使用空格下翻一页,Shift + 空格上翻一页. 但 ...

  9. Redisson 分布式锁源码 11:Semaphore 和 CountDownLatch

    前言 Redisson 除了提供了分布式锁之外,还额外提供了同步组件,Semaphore 和 CountDownLatch. Semaphore 意思就是在分布式场景下,只有 3 个凭证,也就意味着同 ...

  10. 修改gitlab默认的nginx

    目录 1. 修改gitlab的配置文件 2. nginx配置 3. 重载 前言: 本文将介绍,如何禁用gitlab自带的nginx,用已经安装的nginx提供web服务. 1. 修改gitlab的配置 ...