当前位置: 首页 > news >正文

专业建站提供商重庆装修公司平台

专业建站提供商,重庆装修公司平台,wordpress login 图标,国内免费素材网站文章目录 Nacos定义服务注册与订阅方法服务信息加载与配置实现将网关注册到注册中心实现服务的订阅 Nacos Nacos提供了许多强大的功能#xff1a; 比如服务发现、健康检测。 Nacos支持基于DNS和基于RPC的服务发现。 同时Nacos提供对服务的实时的健康检查#xff0c;阻止向不… 文章目录 Nacos定义服务注册与订阅方法服务信息加载与配置实现将网关注册到注册中心实现服务的订阅 Nacos Nacos提供了许多强大的功能 比如服务发现、健康检测。 Nacos支持基于DNS和基于RPC的服务发现。 同时Nacos提供对服务的实时的健康检查阻止向不健康的主机活服务发送请求。 并且Nacos也提供了一个可视化的控制台方便我们对实例等信息进行管理。 同时Nacos提供了动态配置服务可以让我们以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置 Nacos是我在开发自己项目过程中用的最多的一个注册中心和配置中心并且Nacos的社区相对其他的来说更加活跃代码也更加容易阅读。 如下是Nacos官网Nacos官网 我就不再这篇文章里面过多的讲解Nacos的一些特性了。 在这一章节中我将使用Nacos暴露出来的接口来完成项目的服务注册功能以及服务发现功能。 完成这一章的学习也会让你更加深入的了解到Nacos的底层运行原理注册中心原理。 下面是一些我曾经学习Nacos过程中编写的一些文章有兴趣可以看看。 使用Nacos实现动态线程池技术以及Nacos配置文件更新监听事件 【源码分析】Nacos如何使用AP协议完成服务端之间的数据同步 【源码分析】Nacos服务端如何更新以及保存注册表信息 Nacos自动注册原理实现以及服务注册更新并如何保存到注册表 为什么选择Nacos之前的文章简单讲解过这里我将详细的列举出几个原因 Nacos 提供了让我从微服务平台建设的视角管理数据中心的所有服务及元数据具体原因可以看看上面我对Nacos源码的分析Nacos将服务细粒度的划分为了各自实例并且我们可以管理这些实例的信息Nacos支持基于DNS和基于RPC的服务发现这也就意味着提供给我们较强的服务发现的选择能力Nacos提供对服务的实时的健康检查阻止向不健康的主机或服务实例发送请求也就是安全动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置我之前也已经利用过这一点来实现对线程池的动态配置具体可以查看这篇文章 定义服务注册与订阅方法 在这一步我们将需要定义一些网关项目用于连接到Nacos这个注册中心的接口来实现会将我们的项目链接到注册中心。 要将一个服务注册到注册中心大概需要初始化、注册、取消注册、服务订阅等方法也就是我们需要编写一个如下的接口来提供这样子的一个接口并在后面的具体注册中心实例中去实现这个接口方法。 public interface RegisterCenter {/*** 初始化* param registerAddress 注册中心地址* param env 要注册到的环境*/void init(String registerAddress, String env);/*** 注册* param serviceDefinition 服务定义信息* param serviceInstance 服务实例信息*/void register(ServiceDefinition serviceDefinition, ServiceInstance serviceInstance);/*** 注销* param serviceDefinition* param serviceInstance*/void deregister(ServiceDefinition serviceDefinition, ServiceInstance serviceInstance);/*** 订阅所有服务变更* param registerCenterListener*/void subscribeAllServices(RegisterCenterListener registerCenterListener); } 实现完毕接口之后我们还需要提供一个方法它的作用是用于监听注册中心的配置的变更。 这也是Nacos作为注册中心和配置中心特别重要的一个功能接口定义如下 public interface RegisterCenterListener {void onChange(ServiceDefinition serviceDefinition,SetServiceInstance serviceInstanceSet); } 服务信息加载与配置 基于上面的服务注册与订阅接口我们就可以大致编写出来如何将我们的网关注册到Nacos中了。当然我们还没有具体实现如何注册到Nacos注册中心的方法但是我们可以先编写出来其大致的一个调用方法。 Slf4j public class Bootstrap {public static void main( String[] args ){//加载网关核心静态配置Config config ConfigLoader.getInstance().load(args);System.out.println(config.getPort());//插件初始化//配置中心管理器初始化连接配置中心监听配置的新增、修改、删除//启动容器Container container new Container(config);container.start();//连接注册中心将注册中心的实例加载到本地final RegisterCenter registerCenter registerAndSubscribe(config);//服务优雅关机//进程收到kill信号的时候进行一个注销操作Runtime.getRuntime().addShutdownHook(new Thread(){/*** 下线操作*/Overridepublic void run(){registerCenter.deregister(buildGatewayServiceDefinition(config),buildGatewayServiceInstance(config));}});}/*** 当前方法用于提供注册和订阅服务信息变更通知* param config* return*/private static RegisterCenter registerAndSubscribe(Config config) {//加载服务提供者 具体这里的作用可以 查看我的博客ServiceLoaderRegisterCenter serviceLoader ServiceLoader.load(RegisterCenter.class);final RegisterCenter registerCenter serviceLoader.findFirst().orElseThrow(() - {log.error(not found RegisterCenter impl);return new RuntimeException(not found RegisterCenter impl);});//初始化注册中心信息registerCenter.init(config.getRegistryAddress(), config.getEnv());//构造网关服务定义和服务实例ServiceDefinition serviceDefinition buildGatewayServiceDefinition(config);ServiceInstance serviceInstance buildGatewayServiceInstance(config);//注册registerCenter.register(serviceDefinition, serviceInstance);//订阅registerCenter.subscribeAllServices(new RegisterCenterListener() {Overridepublic void onChange(ServiceDefinition serviceDefinition, SetServiceInstance serviceInstanceSet) {log.info(refresh service and instance: {} {}, serviceDefinition.getId(),JSON.toJSON(serviceInstanceSet));DynamicConfigManager manager DynamicConfigManager.getInstance();manager.addServiceInstance(serviceDefinition.getId(), serviceInstanceSet);}});return registerCenter;}/*** 构建网关服务实例* param config* return*/private static ServiceInstance buildGatewayServiceInstance(Config config) {String localIp NetUtils.getLocalIp();int port config.getPort();ServiceInstance serviceInstance new ServiceInstance();serviceInstance.setServiceInstanceId(localIp COLON_SEPARATOR port);serviceInstance.setIp(localIp);serviceInstance.setPort(port);serviceInstance.setRegisterTime(TimeUtil.currentTimeMillis());return serviceInstance;}/*** 构建网关服务定义信息* param config* return*/private static ServiceDefinition buildGatewayServiceDefinition(Config config) {ServiceDefinition serviceDefinition new ServiceDefinition();serviceDefinition.setInvokerMap(Map.of());serviceDefinition.setId(config.getApplicationName());serviceDefinition.setServiceId(config.getApplicationName());serviceDefinition.setEnvType(config.getEnv());return serviceDefinition;}} 其中比较重要的就是这一行代码也就是加载服务提供者 ServiceLoader.load(RegisterCenter.class) ServiceLoader是 Java 中用于加载服务提供者的工具通常用于实现服务提供者框架。它的作用是查找和加载指定接口或抽象类的服务提供者实现类这些实现类在运行时动态注册到系统中以便其他组件或应用程序可以使用它们的功能。 具体来说以下是它的作用和用法 服务接口定义首先您需要定义一个服务接口或抽象类这是您想要不同实现的抽象描述。在您的例子中RegisterCenter.class 似乎是一个服务接口。 服务提供者实现不同的模块或库可以提供服务接口的不同实现这些实现类可以独立于应用程序开发并且可以在运行时加载。 服务提供者注册每个服务提供者实现类需要在 META-INF/services 目录下创建一个文件该文件的名称是服务接口的全限定名内容是服务提供者实现类的全限定名。这告诉 Java 运行时系统哪些类实现了该服务接口。 加载服务提供者使用 ServiceLoader.load(RegisterCenter.class)您可以加载所有已经注册的服务提供者实现类。这返回一个 ServiceLoader 对象您可以迭代这个对象以获取所有已加载的实现类的实例。 这个机制允许应用程序在不修改源代码的情况下动态地切换和使用不同的服务提供者实现从而提高了应用程序的可扩展性和灵活性。它通常用于框架和库以允许开发者插入他们自己的实现例如数据库驱动程序、日志记录器、插件等。 实现将网关注册到注册中心 想要将网关注册到注册中心我们首先需要引入Nacos的客户端依赖。 !--引入Nacos的客户端依赖--dependencygroupIdcom.alibaba.nacos/groupIdartifactIdnacos-client/artifactIdversion2.0.4/version/dependency!--导入我们直接实现的注册中心接口--dependencygroupIdblossom.project/groupIdartifactIdBlossomGateway-Register-Center-Api/artifactIdversion1.0/version/dependency/dependencies之后我们就可以使用Nacos客户端中提供的服务注册方法进行服务注册了。 方式如下 Slf4j public class NacosRegisterCenter implements RegisterCenter {/*** 注册中心的地址*/private String registerAddress;/*** 环境选择*/private String env;/*** 主要用于维护服务实例信息*/private NamingService namingService;/*** 主要用于维护服务定义信息*/private NamingMaintainService namingMaintainService;/*** 监听器列表* 这里由于监听器可能变更 会出现线程安全问题*/private ListRegisterCenterListener registerCenterListenerList new CopyOnWriteArrayList();Overridepublic void init(String registerAddress, String env) {this.registerAddress registerAddress;this.env env;try {this.namingMaintainService NamingMaintainFactory.createMaintainService(registerAddress);this.namingService NamingFactory.createNamingService(registerAddress);} catch (NacosException e) {throw new RuntimeException(e);}}Overridepublic void register(ServiceDefinition serviceDefinition, ServiceInstance serviceInstance) {try {//构造nacos实例信息Instance nacosInstance new Instance();nacosInstance.setInstanceId(serviceInstance.getServiceInstanceId());nacosInstance.setPort(serviceInstance.getPort());nacosInstance.setIp(serviceInstance.getIp());//实例信息可以放入到metadata中nacosInstance.setMetadata(Map.of(GatewayConst.META_DATA_KEY, JSON.toJSONString(serviceInstance)));//注册namingService.registerInstance(serviceDefinition.getServiceId(), env, nacosInstance);//更新服务定义namingMaintainService.updateService(serviceDefinition.getServiceId(), env, 0,Map.of(GatewayConst.META_DATA_KEY, JSON.toJSONString(serviceDefinition)));log.info(register {} {}, serviceDefinition, serviceInstance);} catch (NacosException e) {throw new RuntimeException(e);}} }这里需要对Nacos的源码有了解你才能明白如何将一个服务实例注册到Nacos的注册中心Nacos这边要求你提供服务的ip、端口、服务名称等信息。 完成这一步之后我们大概就已经成功的将服务注册到Nacos了。 实现服务的订阅 这里我们开始实现服务订阅要想实现服务订阅首先需要拉取Nacos上面的所有的服务的信息并且服务信息会不断的更新变化因此我们还需要使用定时任务的方式不断的更新我们的服务订阅信息。 要先实现对Nacos服务信息的订阅需要用到Nacos的事件监听器NamingEvent。 在Nacos注册中心中NamingEvent 是一个事件对象用于表示与服务命名空间Naming相关的事件。NamingEvent 的作用是用于监听和处理命名空间中的服务实例Service Instance的变化以便应用程序可以根据这些变化来动态地更新服务实例列表以保持与注册中心的同步。 具体来说NamingEvent 主要用于以下目的 监听服务实例的变化Nacos注册中心可以包含大量的服务实例而这些实例可能会因服务上线、下线、实例元数据变化等原因而发生变化。NamingEvent 允许应用程序注册监听器以便在服务实例发生变化时得到通知。 动态更新服务实例列表通过监听 NamingEvent应用程序可以实时获得有关服务实例的状态变化从而可以及时更新自己维护的服务实例列表以确保使用最新的服务实例信息。 实现负载均衡应用程序可以根据 NamingEvent 提供的信息来实现负载均衡策略例如选择合适的服务实例以提供服务请求。负载均衡策略可以根据服务实例的可用性、健康状态和其他元数据来进行调整。 动态路由一些应用程序可能需要实现动态路由根据服务实例的变化来动态更新路由规则以确保请求被正确路由到可用的服务实例。 大致的代码实现如下 Overridepublic void subscribeAllServices(RegisterCenterListener registerCenterListener) {//服务订阅首先需要将我们的监听器加入到我们的服务列表中registerCenterListenerList.add(registerCenterListener);//进行服务订阅doSubscribeAllServices();//可能有新服务加入所以需要有一个定时任务来检查ScheduledExecutorService scheduledThreadPool Executors.newScheduledThreadPool(1, new NameThreadFactory(doSubscribeAllServices));//循环执行服务发现与订阅操作scheduledThreadPool.scheduleWithFixedDelay(() - doSubscribeAllServices(), 10, 10, TimeUnit.SECONDS);}private void doSubscribeAllServices() {try {//得到当前服务已经订阅的服务//这里其实已经在init的时候初始化过namingservice了所以这里可以直接拿到当前服务已经订阅的服务//如果不了解的可以debugSetString subscribeService namingService.getSubscribeServices().stream().map(ServiceInfo::getName).collect(Collectors.toSet());int pageNo 1;int pageSize 100;//分页从nacos拿到所有的服务列表ListString serviseList namingService.getServicesOfServer(pageNo, pageSize, env).getData();//拿到所有的服务名称后进行遍历while (CollectionUtils.isNotEmpty(serviseList)) {log.info(service list size {}, serviseList.size());for (String service : serviseList) {//判断是否已经订阅了当前服务if (subscribeService.contains(service)) {continue;}//nacos事件监听器 订阅当前服务//这里我们需要自己实现一个nacos的事件订阅类 来具体执行订阅执行时的操作EventListener eventListener new NacosRegisterListener();eventListener.onEvent(new NamingEvent(service, null));namingService.subscribe(service, env, eventListener);log.info(subscribe {} {}, service, env);}//遍历下一页的服务列表serviseList namingService.getServicesOfServer(pageNo, pageSize, env).getData();}} catch (NacosException e) {throw new RuntimeException(e);}}/*** 实现对nacos事件的监听器* NamingEvent 是一个事件对象用于表示与服务命名空间Naming相关的事件。* NamingEvent 的作用是用于监听和处理命名空间中的服务实例Service Instance的变化* 以便应用程序可以根据这些变化来动态地更新服务实例列表以保持与注册中心的同步。*/public class NacosRegisterListener implements EventListener {Overridepublic void onEvent(Event event) {if (event instanceof NamingEvent) {log.info(the triggered event info is{},JSON.toJSON(event));NamingEvent namingEvent (NamingEvent) event;String serviceName namingEvent.getServiceName();try {//获取服务定义信息Service service namingMaintainService.queryService(serviceName, env);ServiceDefinition serviceDefinition JSON.parseObject(service.getMetadata().get(GatewayConst.META_DATA_KEY),ServiceDefinition.class);//获取服务实例信息ListInstance allInstances namingService.getAllInstances(service.getName(), env);SetServiceInstance set new HashSet();for (Instance instance : allInstances) {ServiceInstance serviceInstance JSON.parseObject(instance.getMetadata().get(GatewayConst.META_DATA_KEY),ServiceInstance.class);set.add(serviceInstance);}registerCenterListenerList.stream().forEach(l - l.onChange(serviceDefinition, set));} catch (NacosException e) {throw new RuntimeException(e);}}}}此时我们就完成了在Nacos注册中心发生信息变更的时候能在一次拉取到最新的配置信息。也就是我们完成了对注册中心的订阅。
http://www.dnsts.com.cn/news/103863.html

相关文章:

  • 手机如何创造网站app排行榜
  • 漯河最新今天的消息网站建设阿华seo
  • 大连网站排名优wordpress4.5.3zhcn
  • 商务网站规划设计要点vs2012 建网站
  • 企业网站和官网的区别如何自己做淘宝客网站
  • 手机上传视频网站开发网上怎么自己注销营业执照
  • 网站头部代码营销策略模板
  • 免费建站网站号如何投放网络广告
  • 夏邑好心情网站建设有限公司扩展名网站
  • 聚美优品网站模版无极电影网首页
  • 外汇平台网站开发需求说明福州商城网站开发公司
  • 新网 网站建设农机局网站建设方案
  • 计算机网络技术电商网站建设与运营方向windows优化大师有哪些功能
  • elementui 做的网站html网页小游戏代码
  • 怎么做网站安全运维泰州哪家做网站建设比较好
  • 2019年建设什么网站好重庆建网站 私单
  • 怎么做qq钓鱼网站吗深圳网站设计公司在哪里
  • 做网站需要多少钱 网络服务视频号直播怎么引流
  • 网站规划建设实训报告网站建站客户需求表单
  • 做响应式网站多少钱论坛类的网站怎么做
  • 装修公司网站怎么做的电子商城网站开发项目描述
  • 企业门户网站源码中国网站备案信息查询
  • 博星卓越营销网站设计网页策划方案模板范文
  • 广州做网站推广的公司网站托管服务 重庆
  • word链接点进去是网站怎么做协会秘书处工作建设 网站
  • 建设部网站办事大厅栏目脱贫地区农副产品网络销售平台
  • 石家庄做网站费用室内设计效果图多少钱
  • 华为怎么设置安全网站网站建设背景需要写些什么
  • 如何知道网站什么时候做的企业所得税是多少
  • 四川做网站找谁网站建设课程的认识