ApacheCuratorFramework教程(二)SpringBoot实现服务发现服务器
Apache Curator Framework教程(二)Spring Boot实现服务发现服务器(Restful API)版本说明
Spring boot: 2.7.8
Curator: 5.0.4
JDK: 17 特别说明
Spring boot版本不能使用3.x以上,我使用3.0.2测试,不通过,目前还没有研究具体原因,暂时使用2.7.8! Curator Service Discovery Server 的依赖 curator-x-discovery-server 是基于JAX-RS实现的,所以Spring boot的web依赖要使用pring-boot-starter-jersey. curator-x-discovery-server已经提供了Restful api的代码, 我们无需自己写,只需要配置即可. 项目说明Maven依赖<?xml version="1.0" encoding="UTF-8"?> 4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.8 cn.programtalk curator-service-discovery-server 0.0.1-SNAPSHOT curator-service-discovery-server curator-service-discovery-server 17 org.springframework.boot spring-boot-starter-jersey org.apache.curator curator-recipes 5.4.0 org.apache.curator curator-x-discovery-server 5.4.0 org.apache.curator curator-test 5.4.0 test org.springframework.boot spring-boot-starter-test test org.projectlombok lombok org.springframework.boot spring-boot-maven-plugin 服务发现服务器配置
需要初始化几个Bean. package cn.programtalk.config; import lombok.SneakyThrows; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.x.discovery.ServiceDiscovery; import org.apache.curator.x.discovery.ServiceDiscoveryBuilder; import org.apache.curator.x.discovery.details.JsonInstanceSerializer; import org.apache.curator.x.discovery.server.contexts.StringDiscoveryContext; import org.apache.curator.x.discovery.server.rest.DiscoveryContext; import org.apache.curator.x.discovery.strategies.RoundRobinStrategy; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.ws.rs.ext.ContextResolver; /** * Curator配置类 * @author programtalk.cn */ @Configuration public class CuratorConfig { // zk服务器连接地址,172.29.240.53:2181,172.29.240.53:2182 @Value("${cn.programtalk.zk-servers}") public String zkServers; // 服务发现在Zk中的根路径 @Value("${cn.programtalk.base-path}") public String basePath; /** * CuratorFramework客户端 * @return */ @Bean public CuratorFramework curatorFramework() { CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient(zkServers, new ExponentialBackoffRetry(1000, 3)); curatorFramework.start(); return curatorFramework; } /** * ServiceDiscovery实例 * @return */ @SneakyThrows @Bean ServiceDiscovery serviceDiscovery() { return ServiceDiscoveryBuilder.builder(String.class) // zk路径 .basePath(basePath) // zk客户端 .client(curatorFramework()) // 是否监听实例 .watchInstances(true) // 序列化 .serializer(new JsonInstanceSerializer<>(String.class)) .build(); } /** * * @return */ @Bean public DiscoveryContext discoveryContext() { return new StringDiscoveryContext(serviceDiscovery(), new RoundRobinStrategy<>(), 30); } @Bean public ContextResolver> resolver() { return aClass -> discoveryContext(); } }
上面这个类,主要配置了CuratorFramework客户端(用于连接Zookeeper),ServiceDiscovery(服务发现配置),DiscoveryContext(服务发现上下文)等. API配置
curator已经实现了Restful Api,他是个抽象类,名字是DiscoveryResource,使用者需要自己创建类并继承DiscoveryResource. package cn.programtalk.api; import org.apache.curator.x.discovery.server.rest.DiscoveryContext; import org.apache.curator.x.discovery.server.rest.DiscoveryResource; import org.springframework.stereotype.Component; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.ext.ContextResolver; /** * 自定义MyResource,继承DiscoveryResource,DiscoveryResource是Curator提供的服务发现服务器的Restful Api. */ @Path("/") @Component public class MyResource extends DiscoveryResource { public MyResource(@Context ContextResolver> resolver) { super(resolver.getContext(DiscoveryContext.class)); } }注册API类
上面创建的MyResource类需要注册到Jersey中. package cn.programtalk.config; import cn.programtalk.api.MyResource; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.context.annotation.Configuration; /** * Jersey配置类 * * @author programtalk.cn */ @Configuration public class JerseyConfig extends ResourceConfig { public JerseyConfig() { // 将自定义的Api类注册 register(MyResource.class); } }application.yamlcn: programtalk: # zookeeper服务信息 zk-servers: 172.29.240.53:2181 # 服务发现的根路径(zookeeper中) base-path: "/service-discovery"API测试
api请求数据结构请看官方说明:https://git-wip-us.apache.org/repos/asf?p=curator.git;a=blob_plain;f=curator-x-discovery-server/README.txt;hb=HEAD putService
注册或者修改服务
请求数据如下: PUT /v1/service/product-service/product-instance-id2 HTTP/1.1 Host: localhost:8080 Content-Type: application/json Content-Length: 224 { "name": "product-service", "id": "product-instance-id2", "address": "10.20.30.40", "port": 1234, "payload": "产品服务payload", "registrationTimeUTC": 1325129459728, "serviceType": "STATIC" }
看下Zk里的节点的信息
可以看到product-service服务里有一个实例product-instance-id1
我再添加几个实例(修改id即可)。
总共添加了三个实例。
用同样的方法再添加另一个订单服务(order-service) PUT /v1/service/order-service/order-instance-id1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json Content-Length: 220 { "name": "order-service", "id": "order-instance-id1", "address": "10.20.30.40", "port": 1234, "payload": "订单服务payload", "registrationTimeUTC": 1325129459728, "serviceType": "STATIC" }
再查看下zk节点情况
也创建了三个实例。 removeService
删除服务下的实例
测试删除order-service的order-instance-id1实例
DELETE /v1/service/order-service/order-instance-id1 HTTP/1.1 Host: localhost:8080
查看订单服务信息
确实已经被删除掉。 get
获取服务下的单个实例
GET /v1/service/order-service/order-instance-id2 HTTP/1.1 Host: localhost:8080getAllNames
查询所有服务名
GET /v1/service HTTP/1.1 Host: localhost:8080getAll
查询服务下的所有实例
GET /v1/service/order-service HTTP/1.1 Host: localhost:8080getAny
随机获取某个服务下的某个实例
GET /v1/anyservice/order-service HTTP/1.1 Host: localhost:8080项目地址
github:https://github.com/ProgramTalk1024/curator-service-discovery-server.git
说明文档
https://itlab1024.com/archives/208.html 运行说明
如果想运行该项目,首先去application.yaml中修改zk的地址。
如今的年轻人沉浸在App里逛超市线上业务拓展,扭转了部分超市的业绩。近日,多家上市的商超零售企业发布财报显示,在布局新的零售模式后,线上零售业务均实现大幅增长。像逛淘宝一样逛超市微信接龙下单自己选择合适的配送时间
思念是一条长长的河纪念奶奶逝世40周年来源湖南日报文曹辉1983年2月,作者(前左)与爷爷奶奶父母弟弟合影。(一)一晃,奶奶走了40年了。其实,按农历,40年忌日早过了。而我从读大学开始,就习惯于大事小事都记阳历,之前
7个国内能打开的AI绘画网站近年来,随着人工智能技术的不断进步,AI绘画已经成为了一个备受关注的领域。如果您正在寻找一些国内的AI绘画网站,可以参考以下推荐。首先,提到的6pen文心大模型Draftnight
浏阳烟花300亿的彷徨与突破如果要用一个词来描述2023年春节假期的夜晚,对于每一个湖南浏阳的烟花人来说,一定有加特林。春节期间,加特林烟花在互联网上铺天盖地地涌向大众,让更多的人关注到了浏阳烟花产业,一个特
鲨鱼房间与龙爪?盘点全网少见的五大游戏彩蛋!(第一期)大家好!我是游鸡队老徐。今天我们将为各位观众姥爷们揭示游戏界最令人惊奇的四大彩蛋!彩蛋本身是游戏开发者们用来增加游戏的趣味性和神秘感而设置的秘密。接下来我会更多地PO出更多的游戏中
盘点CSGO地图中历史级涂鸦彩蛋!相信玩CSGO的小伙伴们对CSGO地图中的涂鸦一定很熟悉,V社为了纪念在CSGO比赛中职业选手惊为天人的操作,经常会以地图涂鸦彩蛋的方式将该场面记录在地图之上,让我们来回顾一下部分
变革武器箱皮肤和间谍胶囊印花的由来及彩蛋2月10日CSGO推出了变革武器箱间谍胶囊和终极音乐盒,其中的一些皮肤和印花受到了不少玩家们的讨论和追捧,当翻查这些饰品的创意工坊后,才发现原来这些饰品设计的这么有意思。变革武器箱
打卡闽江之心这些彩蛋你知道吗?青年桥轻功了得地面圆盘彰显国际范WIFI密码格外有意义位于三县洲大桥与解放大桥之间的闽江之心,被誉为最美水岸城市会客厅。每天到这里打卡的游客络绎不绝。不过福州晚报提醒你,如果步履匆
蚁人3片尾第一个彩蛋说了什么?那么多康居然全是炮灰!相信许多观众看完蚁人3量子狂潮后,都对影片结尾的两个彩蛋感到好奇,今天我们就来着重分析影片第一个彩蛋,并探索其对于复联5的影响。注意以下内容涉及剧透!注意以下内容涉及剧透!注意以下
听过来人的话,别去看蚁人3量子狂热,彩蛋,我告诉你啊票根证明我看过,还是IMAX的我就不说太多没用的,直接说感想吧首先,剧情极其老套。就是某人失误酿成大错,把某人祖孙三代都坑苦了,之后某人在量子世界与大魔头对抗,拯救伐木累,顺便阻止
赛博朋克2077致敬终结者的彩蛋,很多玩家都没发现这个细节提到一部好莱坞的经典科幻片,想必很多人第一时间会联想到卡梅隆导演的电影终结者,这部电影算得上是无数人的经典回忆了,因此,我们可以看到很多游戏都有过或多或少致敬终结者的彩蛋,连官方自