解决Springcloud Nacos 开发环境多服务在线乱入问题

1、遇到的问题

         有A,B,C 三个微服务,在服务器s1上部署,我本地开发A微服务和B微服务接口的时候,希望我自己机器的A能调用的我自己机器的B上来,如果我自己没有启动B在调用到S1的B上去。默认情况下我可能调用了多次B 只有一半几率命中到我自己机器,其他的请求都跑到S1去了。

2、解决思路

       一般情况我们使用 ribbon 来做负载均衡,也就是说,具体调用哪个微服务是 ribbon 说了算,我们可以自定义ribbon的负载均衡规则来让他优先将请求命中到我自己这台机器上。

3、自定义规则代码

/**
 * nacos dev环境微服务调度规则
 * 优先同IP,第二同网段
 * debugger.local-ip 请配置为本机在nacos上的那个IP
 * by 王磊
 */
public class DevNacosDebuggerRuleConfig extends AbstractLoadBalancerRule {

    @Value("${debugger.local-ip:}")
    private String localIp;

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    /**
     * 重写choose方法
     *
     * @param key
     * @return
     */
    @SneakyThrows
    @Override
    public Server choose(Object key) {
        //获取负载均衡器
        BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) getLoadBalancer();
        //调用服务的名字
        String invokedServerName = baseLoadBalancer.getName();
        //获取namingServer(包含nacos注册发现相关api)
        NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
        //获取被调用的服务的所有实例
        List<Instance> invokedAllInstanceList = namingService.getAllInstances(invokedServerName);
        if (invokedAllInstanceList.isEmpty()) {
            throw new RuntimeException(invokedServerName + "找不到服务,请检查服务提供者是否已经启动并且已经注册到nacos中");
        }
        Instance invokedInstance = null;
        String localIp = this.getLocalhostIp();
        //192.168.0  获取到同网段ip
        String localIpStart = localIp.substring(0, localIp.lastIndexOf("."));
        //他的优先级比较高
        Instance l1InvokedInstance = null;
        for (Instance instance : invokedAllInstanceList) {
            if (instance.getIp().equals(localIp)) {
                return new NacosServer(instance);
            } else if (instance.getIp().startsWith(localIpStart)) {
                invokedInstance = instance;
            } else if (instance.getIp().equals("192.168.16.229")) {
                l1InvokedInstance = instance;
            }
        }
        invokedInstance = l1InvokedInstance == null ? invokedInstance : l1InvokedInstance;
        return new NacosServer(invokedInstance != null ? invokedInstance : invokedAllInstanceList.get(0));
    }


    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    /**
     * 获取本地ip
     *
     * @return 本机ip
     */
    public String getLocalhostIp() {
        if (!StringUtils.isEmpty(localIp)) {
            return localIp;
        }
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress ip = (InetAddress) addresses.nextElement();
                    if (ip != null
                            && ip instanceof Inet4Address
                            && !ip.isLoopbackAddress() //loopback地址即本机地址,IPv4的loopback范围是127.0.0.0 ~ 127.255.255.255
                            && ip.getHostAddress().indexOf(":") == -1) {
                        return ip.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、yml中配置哪些微服务使用此规则

purchase: #purchase 是微服务名字要和nacos里注册的一致
  ribbon:
    NFLoadBalancerRuleClassName: com.xx.bos.gateway.config.DevNacosDebuggerRuleConfig

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Nacos是一个非常流行的微服务注册中心和配置中心,而Ribbon则是一个负载均衡组件。结合起来,可以实现服务的自动发现和负载均衡。 下面是一个简单的示例: 1. 在pom.xml文件中添加依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> ``` 2. 在application.properties或application.yml中配置Nacos和Ribbon: ```yaml # Nacos配置 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 # Ribbon配置 service-provider.ribbon.listOfServers=localhost:8081,localhost:8082 service-provider.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList ``` 3. 创建一个Ribbon的配置类,用于自定义负载均衡策略等: ```java @Configuration public class RibbonConfig { @Bean public IRule ribbonRule() { return new RandomRule(); // 随机负载均衡策略 } @Bean public IPing ribbonPing() { return new PingUrl(false, "/health"); // 检查服务健康状态的URL } } ``` 4. 在服务消费方的代码中,注入RestTemplate对象,并使用@LoadBalanced注解: ```java @RestController public class ConsumerController { @Autowired private RestTemplate restTemplate; @GetMapping("/hello") public String hello() { String url = "http://service-provider/hello"; return restTemplate.getForObject(url, String.class); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } } ``` 在这里,我们使用了"http://service-provider/hello"作为服务提供方的URL,而不是具体的IP和端口。这是因为Ribbon会根据服务名自动选择一个可用的实例。 以上就是使用Spring Cloud Nacos和Ribbon调用服务的基本步骤。需要注意的是,在使用Nacos作为注册中心时,服务提供方需要在启动时注册自己。可以参考Nacos的官方文档或者Spring Cloud官方文档进行配置和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值