内容简介:Spring Cloud Netflix Eureka集群配置方式主要用两种:Static servers list config和dns,本文主要介绍基于DNS的方式搭建Eureka集群。client启动后从config中获取region和zone以及serviceUrl,进行服务注册、发现,这种静态集群模式无法动态扩容,一旦新增节点,只能挨个修改server和client端的配置文件,大致配置如下:基于DNS的Eureka Cluster架构图如下:
Spring Cloud Netflix Eureka集群配置方式主要用两种:Static servers list config和dns,本文主要介绍基于DNS的方式搭建Eureka集群。
Static servers list config
client启动后从config中获取region和zone以及serviceUrl,进行服务注册、发现,这种静态集群模式无法动态扩容,一旦新增节点,只能挨个修改server和client端的配置文件,大致配置如下:
eureka: server: enable-self-preservation: false instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://10.25.102.174:8082/eureka/,http://10.25.102.174:8083/eureka/
DNS configuration
基于DNS的Eureka Cluster架构图如下:
简单来说就是使用DNS服务器管理Eureka Server的地址,弹性伸缩对客户端没有影响。
大致流程如下:
use-dns-for-fetching-service-urls: true client.region "http://" + ec2Url + ":" + clientConfig.getEurekaServerPort() + "/" + clientConfig.getEurekaServerURLContext() + "/";
只要解决DNS服务器配置就可以达到动态集群的效果,关于如何搭建DNS服务器集群,请移步另一篇文章: CentOS 搭建DNS主从服务器集群 ,文中详细介绍了如何在区域配置文件中配置TXT记录,本文不在赘述。
1.DNS 区域文件配置TXT记录
zts.local.zone区域配置文件中有关eureka的配置:
; eureka cluster配置 txt.shanghai IN TXT "defaultZone.zts.local" txt.defaultZone IN TXT "10.29.181.56" "10.29.181.57" "10.29.181.58" "10.29.181.60" ;通过查看Eureka的源码,它的实现是通过寻找txt.beijing-a.zts.local(txt.region.eureka-server-d-n-s-name)获取"beijing-a.zts.local" "beijing-b.zts.local"的zone:beijing-a和beijing-b, ;然后再去获取txt.beijing-a.zts.local和txt.beijing-b.zts.local中对应的ServiceUrls的数据,也就是IP地址: "10.29.181.61" "10.29.181.62" ;这样服务间就可以获取到固定端口下的不同IP的机器的注册中心服务地址,并相互注册 txt.beijing IN TXT "beijing-a.zts.local" "beijing-b.zts.local" txt.beijing-a IN TXT "10.29.181.61" "10.29.181.62" txt.beijing-b IN TXT "10.29.181.63" "10.29.181.64"
2.Eureka Server/Client端配置
--- spring: application: name: eureka-server server: port: 8081 eureka: server: enable-self-preservation: false instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: ## 是否将自己注册到eureka register-with-eureka: true ## 是否获取注册信息到本地 fetch-registry: true ## 开启DNS方式获取serviceUrl,默认为false use-dns-for-fetching-service-urls: true ## DNS域名,获取其他信息将以该域名为根域名 eureka-server-d-n-s-name: zts.local ## 当前应用所在区域,默认为us-east-1 region: beijing ## 配置中心的eureka目录 eureka-server-u-r-l-context: eureka ## 映射其他eurekaServer的端口,这里注意采用这种方式 server.port和这个端口最好一致 ## 因为dns是控制地址的变化,端口不变,所以不像前面的哪些配置方式可以自己定义url和port。 ## 所以每个IP都是用的相同的port进行注册中心服务的部署 eureka-server-port: 8081 ## 获取serviceUrl时候是否优先获取相同zone的列表(如果获取为空则获取所在region第一个zone),如果为false则优先获取不在相同zone的列表 prefer-same-zone-eureka: true
3.测试
修改客户端DNS服务器配置为10.29.181.61,DNS服务器的域名为zts.local
依次启动4台Eureka Server服务器,查看启动日志(删减版的日志),:
2018-11-20 16:17:14.962 INFO 49750 --- [ main] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via DNS: txt.beijing.zts.local (<------注意这里) 2018-11-20 16:17:15.012 INFO 49750 --- [ main] com.netflix.discovery.DiscoveryClient : Disable delta property : false 2018-11-20 16:17:15.262 INFO 49750 --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1542701835260 with initial instances count: 5 2018-11-20 16:17:15.326 INFO 49750 --- [ main] c.n.eureka.DefaultEurekaServerContext : Initializing ... 2018-11-20 16:17:15.559 INFO 49750 --- [ main] c.n.eureka.cluster.PeerEurekaNodes : Replica node URL: http://10.29.181.62:8081/eureka/ 2018-11-20 16:17:15.560 INFO 49750 --- [ main] c.n.eureka.cluster.PeerEurekaNodes : Replica node URL: http://10.29.181.64:8081/eureka/ 2018-11-20 16:17:15.560 INFO 49750 --- [ main] c.n.eureka.cluster.PeerEurekaNodes : Replica node URL: http://10.29.181.61:8081/eureka/ 2018-11-20 16:17:16.052 INFO 49750 --- [ Thread-14] o.s.c.n.e.server.EurekaServerBootstrap : isAws returned false 2018-11-20 16:17:16.053 INFO 49750 --- [ Thread-14] o.s.c.n.e.server.EurekaServerBootstrap : Initialized server context 2018-11-20 16:17:16.056 INFO 49750 --- [ main] c.z.e.server.EurekaServerApplication : Started EurekaServerApplication in 7.112 seconds (JVM running for 7.625) 2018-11-20 16:17:16.060 INFO 49750 --- [ Thread-14] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.61:eureka-server:8081 with status UP (replication=true) 2018-11-20 16:17:16.061 INFO 49750 --- [ Thread-14] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.62:eureka-server:8081 with status UP (replication=true) 2018-11-20 16:17:16.061 INFO 49750 --- [ Thread-14] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.64:eureka-server:8081 with status UP (replication=true) 2018-11-20 16:17:16.062 INFO 49750 --- [ Thread-14] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.63:eureka-server:8081 with status UP (replication=true) 2018-11-20 16:17:16.062 INFO 49750 --- [ Thread-14] c.n.e.registry.AbstractInstanceRegistry : Registered instance ACCOUNT-CENTER/10.25.102.174:account-center:8891 with status UP (replication=true) 2018-11-20 16:17:16.062 INFO 49750 --- [ Thread-14] c.n.e.r.PeerAwareInstanceRegistryImpl : Got 5 instances from neighboring DS node 2018-11-20 16:17:16.062 INFO 49750 --- [ Thread-14] c.n.e.r.PeerAwareInstanceRegistryImpl : Renew threshold is: 8 2018-11-20 16:17:16.062 INFO 49750 --- [ Thread-14] c.n.e.r.PeerAwareInstanceRegistryImpl : Changing status to UP 2018-11-20 16:17:16.070 INFO 49750 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-SERVER/10.29.181.63:eureka-server:8081 - registration status: 204 2018-11-20 16:17:16.070 INFO 49750 --- [ Thread-14] e.s.EurekaServerInitializerConfiguration : Started Eureka Server 2018-11-20 16:17:16.310 INFO 49750 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-11-20 16:17:16.310 INFO 49750 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-11-20 16:17:16.327 INFO 49750 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms 2018-11-20 16:17:16.578 INFO 49750 --- [nio-8081-exec-1] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.63:eureka-server:8081 with status UP (replication=true) 2018-11-20 16:17:17.457 INFO 49750 --- [nio-8081-exec-2] c.n.e.registry.AbstractInstanceRegistry : Registered instance EUREKA-SERVER/10.29.181.63:eureka-server:8081 with status UP (replication=true)
Eureka Client端
Account服务配置
logging: level: org.springframework.boot: info org.springframework.cloud: debug spring: application: name: account-center server: port: 8891 eureka: server: enable-self-preservation: false instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} metadata-map: configPath: ${server.servlet.context-path} home-page-url-path: ${server.servlet.context-path} ## 服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除 lease-expiration-duration-in-seconds: 10 ## 服务刷新时间配置,每隔这个时间会主动心跳一次 lease-renewal-interval-in-seconds: 5 client: ## 是否将自己注册到eureka register-with-eureka: true ## 是否获取注册信息到本地 fetch-registry: true ## 开启DNS方式获取serviceUrl,默认为false use-dns-for-fetching-service-urls: true ## DNS域名,获取其他信息将以该域名为根域名 eureka-server-d-n-s-name: zts.local ## 当前应用所在区域,默认为us-east-1 region: beijing ## 配置中心的eureka目录 eureka-server-u-r-l-context: eureka ## 映射其他eurekaServer的端口,这里注意采用这种方式 server.port和这个端口最好一致 ## 因为dns是控制地址的变化,端口不变,所以不像前面的哪些配置方式可以自己定义url和port。 ## 所以每个IP都是用的相同的port进行注册中心服务的部署 eureka-server-port: 8081 ## 获取serviceUrl时候是否优先获取相同zone的列表(如果获取为空则获取所在region第一个zone),如果为false则优先获取不在相同zone的列表 prefer-same-zone-eureka: true
Account启动日志:
2018-11-20 16:11:05.373 INFO 5824 --- [ restartedMain] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via DNS: txt.beijing.zts.local (<------看这里) 2018-11-20 16:11:05.529 INFO 5824 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Disable delta property : false 2018-11-20 16:11:05.529 INFO 5824 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null 2018-11-20 16:11:05.529 INFO 5824 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false 2018-11-20 16:11:05.529 INFO 5824 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Application is null : false 201
打开Eureka console,查看注册效果:
参考资料
1.com.netflix.discovery.endpoint.EndpointUtils.getServiceUrlsFromDNS
版本:eureka-client:1.9.3
/** * Get the list of all eureka service urls for the eureka client to talk to. * * @param clientConfig the clientConfig to use * @param zone the zone in which the client resides * @param randomizer a randomizer to randomized returned urls, if loading from dns * * @return The list of all eureka service urls for the eureka client to talk to. */ public static List<String> getDiscoveryServiceUrls(EurekaClientConfig clientConfig, String zone, ServiceUrlRandomizer randomizer) { boolean shouldUseDns = clientConfig.shouldUseDnsForFetchingServiceUrls(); if (shouldUseDns) { return getServiceUrlsFromDNS(clientConfig, zone, clientConfig.shouldPreferSameZoneEureka(), randomizer); } return getServiceUrlsFromConfig(clientConfig, zone, clientConfig.shouldPreferSameZoneEureka()); } /** * Get the list of all eureka service urls from DNS for the eureka client to * talk to. The client picks up the service url from its zone and then fails over to * other zones randomly. If there are multiple servers in the same zone, the client once * again picks one randomly. This way the traffic will be distributed in the case of failures. * * @param clientConfig the clientConfig to use * @param instanceZone The zone in which the client resides. * @param preferSameZone true if we have to prefer the same zone as the client, false otherwise. * @param randomizer a randomizer to randomized returned urls * * @return The list of all eureka service urls for the eureka client to talk to. */ public static List<String> getServiceUrlsFromDNS(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone, ServiceUrlRandomizer randomizer) { String region = getRegion(clientConfig); // Get zone-specific DNS names for the given region so that we can get a // list of available zones Map<String, List<String>> zoneDnsNamesMap = getZoneBasedDiscoveryUrlsFromRegion(clientConfig, region); Set<String> availableZones = zoneDnsNamesMap.keySet(); List<String> zones = new ArrayList<String>(availableZones); if (zones.isEmpty()) { throw new RuntimeException("No available zones configured for the instanceZone " + instanceZone); } int zoneIndex = 0; boolean zoneFound = false; for (String zone : zones) { logger.debug("Checking if the instance zone {} is the same as the zone from DNS {}", instanceZone, zone); if (preferSameZone) { if (instanceZone.equalsIgnoreCase(zone)) { zoneFound = true; } } else { if (!instanceZone.equalsIgnoreCase(zone)) { zoneFound = true; } } if (zoneFound) { logger.debug("The zone index from the list {} that matches the instance zone {} is {}", zones, instanceZone, zoneIndex); break; } zoneIndex++; } if (zoneIndex >= zones.size()) { if (logger.isWarnEnabled()) { logger.warn("No match for the zone {} in the list of available zones {}", instanceZone, zones.toArray()); } } else { // Rearrange the zones with the instance zone first for (int i = 0; i < zoneIndex; i++) { String zone = zones.remove(0); zones.add(zone); } } // Now get the eureka urls for all the zones in the order and return it List<String> serviceUrls = new ArrayList<String>(); for (String zone : zones) { for (String zoneCname : zoneDnsNamesMap.get(zone)) { List<String> ec2Urls = new ArrayList<String>(getEC2DiscoveryUrlsFromZone(zoneCname, DiscoveryUrlType.CNAME)); // Rearrange the list to distribute the load in case of multiple servers if (ec2Urls.size() > 1) { randomizer.randomize(ec2Urls); } for (String ec2Url : ec2Urls) { StringBuilder sb = new StringBuilder() .append("http://") .append(ec2Url) .append(":") .append(clientConfig.getEurekaServerPort()); if (clientConfig.getEurekaServerURLContext() != null) { if (!clientConfig.getEurekaServerURLContext().startsWith("/")) { sb.append("/"); } sb.append(clientConfig.getEurekaServerURLContext()); if (!clientConfig.getEurekaServerURLContext().endsWith("/")) { sb.append("/"); } } else { sb.append("/"); } String serviceUrl = sb.toString(); logger.debug("The EC2 url is {}", serviceUrl); serviceUrls.add(serviceUrl); } } } // Rearrange the fail over server list to distribute the load String primaryServiceUrl = serviceUrls.remove(0); randomizer.randomize(serviceUrls); serviceUrls.add(0, primaryServiceUrl); if (logger.isDebugEnabled()) { logger.debug("This client will talk to the following serviceUrls in order : {} ", (Object) serviceUrls.toArray()); } return serviceUrls; }
2. dns config配置参考文章
- micro-service-discovery-using-netflix-eureka
- eureka集群基于DNS配置方式 (给予我了不少灵感)
- Spring Cloud Eureka 集群使用DNS方式进行服务分区 (– 简单介绍了windows dns搭建)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
测出转化率:营销优化的科学与艺术
【美】高尔德(Goward,C.) / 谭磊、唐捷译 / 电子工业出版社 / 2014-10-1 / 68.00元
本书作者通过已成功实现大幅提升转化率的案例,展示了大量以营销为核心的电子商务网站的测试设计方法及转化优化方案。书中作者强调了测试及优化思维的重要性,并就实现方法做了详细讲解。 通过本书,读者将学到如何能够在网站遇到发展和收入瓶颈时,测试出存在的问题并找到解决方案;如何可以深入地了解客户需求,并以此为基础优化网站,使其达到提升转化率的目的;如何提升网站的竞争优势,把在线营销渠道变成高效的转化通......一起来看看 《测出转化率:营销优化的科学与艺术》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
HSV CMYK 转换工具
HSV CMYK互换工具