spring cloud-跨区域集群部署

倾然丶 夕夏残阳落幕 提交于 2020-12-17 15:24:27

 

 

基于springCloud Gateway ,自定义路由规则的方式实现跨区域集群部署。

API 服务 指定 spring.cloud.consul.discovery.instanceZone参数指定  zone 注册到 consul 

Oauth2ApiApplication        server.port=9501;spring.cloud.consul.discovery.instanceZone=zone1

Oauth2ApiApplication-2     server.port=9502;spring.cloud.consul.discovery.instanceZone=zone2

Oauth2ApiApplication-3     server.port=9503;spring.cloud.consul.discovery.instanceZone=zone1

gateway 服务同样通过 指定 spring.cloud.consul.discovery.instanceZone参数指定  zone  从 consul 获取服务

Oauth2GatewayApplication        server.port=8080;spring.cloud.consul.discovery.instanceZone=zone1

Oauth2GatewayApplication-2     server.port=8081;spring.cloud.consul.discovery.instanceZone=zone2

 

spring:
  cloud:
    gateway:
      routes: #配置路由路径
        - id: jxlg-gateway-api
          uri: lb://jxlg-gateway-api
          predicates:
            - Path=/api/**
          filters:
            - StripPrefix=1
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能
          lower-case-service-id: true #使用小写服务名,默认是大写
jxlg-gateway-api:
  ribbon:
    NFLoadBalancerRuleClassName: com.jxlg.gateway.server.config.GateWayLoadBalanceRule

 

GateWayLoadBalanceRule 参考 com.netflix.loadbalancer.RandomRule  实现一个随机获取的 方法 ,通过 

spring.cloud.consul.discovery.instanceZone 对 zone 进行过滤,只路由到相同zone 的区域,后续可以扩展。

 


import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Value;

/**
 * @author admin
 * @date 2020/12/17 10:27
 */
public class GateWayLoadBalanceRule extends AbstractLoadBalancerRule {
    @Value("${spring.cloud.consul.discovery.instanceZone}")
    private String zone;
    private static final Log log = LogFactory.getLog(GateWayLoadBalanceRule.class);

    @Override
    public Server choose(Object key) {
        log.info("key is " + key);
        List<Server> servers = this.getLoadBalancer().getReachableServers();
        servers = servers.stream().filter(server -> zone.equals(server.getZone())).collect(Collectors.toList());;

        log.info("servers " + servers);
        if (servers.isEmpty()) {
            return null;
        }
        if (servers.size() == 1) {
            return servers.get(0);
        }
        return randomChoose(servers);
    }
    /**
     *
     * <p>随机返回一个服务实例 </p>
     * @param servers 服务列表
     */
    private Server randomChoose(List<Server> servers) {
        int randomIndex = RandomUtils.nextInt(servers.size());
        return servers.get(randomIndex);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}

 

api 接口 指定方式

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 测试接口
 * Created by admin on 2020/12/09.
 */
@RestController
public class HelloController {
    @Value("${spring.cloud.consul.discovery.instanceZone}")
    private String zone;

    @GetMapping("/hello")
    public String hello() {
        return "{\"zone\"=\"" + zone + "\"}";
    }

}

使用 postman 测试,应用只会通过 gateway  路由到 相同 zone 区域下的应用。

 

 

 

 

 

 

 

 

 

 

 

 


 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!