IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring-cloud-consul-discovery避坑 -> 正文阅读

[Java知识库]spring-cloud-consul-discovery避坑

背景

背景如上一篇文章《request.getRequestDispatcher().forward()的妙用以及DispatcherType 对Filter配置的影响》,项目要将服务从虚拟机从迁入docker中,方便自动化部署以及弹性扩容等。

闭坑一-应用看到的ip及port是docker的内部ip、端口,外部无法访问

在这里插入图片描述
应用看到的是docker内部ip及端口,这个是宿主机虚拟出来的,对外部不可见;如果不做任何处理,应用会拿着这个ip及docker去注册服务,导致外部调用方调用失败。

处理方法

在这里插入图片描述
这个是所有厂商面临的问题,因此厂商一般会在docker中提供一种方法去获取宿主机的IP,以及宿主机的映射端口,比如我司就是将这两个信息写入环境变量了,应用层可以通过System.getProperties()获取,或者通过spring的Environment获取(spring会将系统变量存入Environment中)。
然后通过实现ConsulRegistrationCustomizer对consul的注册信息进行定制。

# getHostPort()getHostIP()大家根据各自云服提供厂商的解决方案适配
public class ConsulRegistrationCustomizerForDocker implements ConsulRegistrationCustomizer
    @Override
    public void customize(ConsulRegistration registration) {
        if (isRunningInHisDcoker()) {
            registration.getService().setPort(getHostPort());
            registration.getService().setAddress(getHostIP());
        }
    }
}

具体原理参考spring-cloud-consul-discovery自动配置的源码
org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration#consulRegistration

	@Bean
	@ConditionalOnMissingBean
	public ConsulAutoRegistration consulRegistration(
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
			ConsulDiscoveryProperties properties, ApplicationContext applicationContext,
			ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
			ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
			HeartbeatProperties heartbeatProperties) {
		return ConsulAutoRegistration.registration(autoServiceRegistrationProperties,
				properties, applicationContext, registrationCustomizers.getIfAvailable(),
				managementRegistrationCustomizers.getIfAvailable(), heartbeatProperties);
	}

org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration#registration

	public static ConsulAutoRegistration registration(
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
			ConsulDiscoveryProperties properties, ApplicationContext context,
			List<ConsulRegistrationCustomizer> registrationCustomizers,
			List<ConsulManagementRegistrationCustomizer> managementRegistrationCustomizers,
			HeartbeatProperties heartbeatProperties) {

		NewService service = new NewService();
		String appName = getAppName(properties, context.getEnvironment());
		service.setId(getInstanceId(properties, context));
		# 重点关注,下面一节会用到这里
		if (!properties.isPreferAgentAddress()) {
			service.setAddress(properties.getHostname());
		}
		service.setName(normalizeForDns(appName));
		service.setTags(createTags(properties));
		service.setEnableTagOverride(properties.getEnableTagOverride());
		service.setMeta(getMetadata(properties));

		if (properties.getPort() != null) {
			service.setPort(properties.getPort());
			// we know the port and can set the check
			setCheck(service, autoServiceRegistrationProperties, properties, context,
					heartbeatProperties);
		}

		ConsulAutoRegistration registration = new ConsulAutoRegistration(service,
				autoServiceRegistrationProperties, properties, context,
				heartbeatProperties, managementRegistrationCustomizers);
		# here,就是使用ConsulRegistrationCustomizer对注册信息进行定制
		customize(registrationCustomizers, registration);
		return registration;
	}

闭坑二-有时候大家会在虚拟机中配置/etc/hosts,来隔离环境的差异或者说ip的变化,如果hosts中给本机ip也配置了域名(别名,属于私有的,域名系统无法识别),因consul-discovery注册服务时,优先使用域名而不是ip;一般docker中无法去配置hosts(不会让人随便登录进去配置,而且每次重新部署docker都会重建、重新配置,不太可行),导致该域名无法识别,服务间调用不通

解决方案

配置pring.cloud.consul.discovery.preferAgentAddress=true
从上面代码中可以看到address的设置逻辑

		if (!properties.isPreferAgentAddress()) {
			service.setAddress(properties.getHostname());
		}

ConsulDiscoveryProperties源码

	public String getHostname() {
		return this.preferIpAddress ? this.ipAddress : this.hostname;
	}
	public ConsulDiscoveryProperties(InetUtils inetUtils) {
		this();
		this.hostInfo = inetUtils.findFirstNonLoopbackHostInfo();
		this.ipAddress = this.hostInfo.getIpAddress();
		this.hostname = this.hostInfo.getHostname();
	}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:39:48  更:2022-04-28 11:42:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:48:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码