Kevin's blog Kevin's blog
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档

Kevin

你可以迷茫,但不可以虚度
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档
  • 手册教程

  • 技术应用

    • 工作杂货

      • Jprofiler排查
      • ES查询压测
      • 阿尔萨斯(Arthas)
      • 定时任务
      • DruidDataSource配置
      • Spring Cloud Stream
      • 线上Tomcat配置参考
      • 配置Prometheus及健康检测
      • Feign远程调用
      • Hystrix单方法熔断配置
      • 本地开发联调配置
        • 1 覆盖远程Apollo配置
        • 2 Feign Ribbon负载均衡配置
      • Java代码杂记
      • SQL脚本杂记
      • 批量算费本地工具类
      • Apollo配置模糊查询
      • 开发问题记录
      • 机器配置参考
    • 技巧备忘

  • 流程规范

  • GitHub技巧

  • VPN

  • Git笔记

  • 实用手册
  • 技术应用
  • 工作杂货
luoxiaofeng
2022-05-14
目录

本地开发联调配置

提示

以下配置勿提交到Git

# 1 覆盖远程Apollo配置

本地配置优先,覆盖远程Apollo配置

优先级:命令行参数 > 环境变量 > bootstrap.yml > application.properties > apollo config

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

@Profile("dev")
@Configuration
public class PropertyOrderProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered {

  private ConfigurableEnvironment environment;

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    MutablePropertySources propertySources = environment.getPropertySources();
    PropertySource<?> propertySource = propertySources.get("applicationConfig: [classpath:/application.yml]");
    if (null != propertySource) {
      propertySources.addFirst(propertySource);
    }
    propertySource = propertySources.get("applicationConfig: [classpath:/application.properties]");
    if (null != propertySource) {
      propertySources.addFirst(propertySource);
    }
    propertySource = propertySources.get("applicationConfig: [classpath:/bootstrap.yml]");
    if (null != propertySource) {
      propertySources.addFirst(propertySource);
    }
  }

  @Override
  public void setEnvironment(Environment environment) {
    this.environment = (ConfigurableEnvironment) environment;
  }

  @Override
  public int getOrder() {
    return Ordered.LOWEST_PRECEDENCE;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 2 Feign Ribbon负载均衡配置

以本地服务优先,可添加服务->IP:端口映射

优先级:本地服务 > 配置映射的服务 > 注册中心可连接的服务 > 随机服务

import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.MyDataCenterInfo;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

@Slf4j
@Profile("dev")
@Scope("prototype")
@Component
public class LocalLoadbalancerRule extends AbstractLoadBalancerRule {

  private String localHost;

  private Map<String, InetSocketAddress> serverMap = new HashMap<>();

  public LocalLoadbalancerRule() {
    init();
    log.info("创建LocalLoadbalancerRule对象");
  }

  private void init() {
    try {
      // 获取本机服务器地址
      InetAddress inetAddress = InetAddress.getLocalHost();
      this.localHost = inetAddress.getHostAddress();

      // 添加服务映射
      // serverMap.put("yllmdmapi", new InetSocketAddress("10.33.61.13", 31418));
      // serverMap.put("ylwaybillapi", new InetSocketAddress("10.33.61.15", 32343));
      // serverMap.put("yl-platform-i18n-api", new InetSocketAddress("10.33.61.14", 30468));
      // serverMap.put("ylnetworkapi", new InetSocketAddress("10.33.61.14", 31753));
      // serverMap.put("ylassapi", new InetSocketAddress("10.33.61.11", 31686));
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }

  @Override
  public Server choose(Object key) {
    List<Server> allServers = getLoadBalancer().getAllServers();
    if (allServers == null || allServers.size() == 0) {
      return null;
    }

    // 如果本地服务启了,优先使用本地服务
    for (Server server : allServers) {
      String host = server.getHost();
      if (Objects.equals(host, localHost)) {
        return server;
      }
    }

    // 获取配置映射的服务,存在直接就用它
    Server mappingServer = getMappingServer();
    if (mappingServer != null) {
      return mappingServer;
    }

    // 判断注册中心是否有可用服务,有的话直接返回
    for (Server server : allServers) {
      String host = server.getHost();
      int port = server.getPort();
      if (isHostConnectable(host, port)) {
        return server;
      }
    }

    // 无可用服务,随机返回一个服务
    Random random = new Random();
    return allServers.get(random.nextInt(allServers.size()));
  }

  /**
   * 判断服务是否可连接
   *
   * @param host 域名
   * @param port 端口
   * @return 是否可连接
   */
  private boolean isHostConnectable(String host, int port) {
    Socket socket = new Socket();
    try {
      socket.connect(new InetSocketAddress(host, port), 500);
    } catch (IOException e) {
      log.error("服务({}:{})连接不可用", host, port);
      return false;
    } finally {
      try {
        socket.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return true;
  }

  /**
   * 获取配置的服务映射
   */
  private Server getMappingServer() {
    BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) getLoadBalancer();
    String serverName = baseLoadBalancer.getName();

    if (!serverMap.containsKey(serverName)) {
      return null;
    }

    // 根据服务映射创建实例
    InetSocketAddress address = serverMap.get(serverName);
    InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder()
            .setInstanceId(serverName)
            .setHostName(address.getHostName())
            .setIPAddr(address.getHostName())
            .setPort(address.getPort())
            .setDataCenterInfo(new MyDataCenterInfo(DataCenterInfo.Name.MyOwn))
            .setAppName(serverName)
            .build();
    return new DiscoveryEnabledServer(instanceInfo, false, true);
  }

  @Override
  public void setLoadBalancer(ILoadBalancer lb) {

    if (lb == null) {
      log.info("setLoadBalancer调用:{}", "null");
    } else {
      BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) lb;
      String serverName = baseLoadBalancer.getName();
      log.info("setLoadBalancer调用:{}", serverName);
    }

    super.setLoadBalancer(lb);
  }

  @Override
  public ILoadBalancer getLoadBalancer() {
    return super.getLoadBalancer();
  }

  @Override
  public void initWithNiwsConfig(IClientConfig iClientConfig) {
    log.info("initWithNiwsConfig调用:{}", iClientConfig == null ? "null" : iClientConfig.getClientName());
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
上次更新: 2022/06/02, 11:20:10
Hystrix单方法熔断配置
Java代码杂记

← Hystrix单方法熔断配置 Java代码杂记→

最近更新
01
AI是如何学习的
06-05
02
chatGpt提示原则
06-05
03
提示词工程实践指南
06-05
更多文章>
| Copyright © 2022-2025 Kevin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式