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

在人才网站做业务/阿里云模板建站

在人才网站做业务,阿里云模板建站,泡泡h5网页制作,手机论坛文章目录 Nacos定义服务注册与订阅方法服务信息加载与配置实现将网关注册到注册中心实现服务的订阅 Nacos Nacos提供了许多强大的功能: 比如服务发现、健康检测。 Nacos支持基于DNS和基于RPC的服务发现。 同时Nacos提供对服务的实时的健康检查,阻止向不…

文章目录

  • 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,Set<ServiceInstance> 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) {//加载服务提供者  具体这里的作用可以 查看我的博客ServiceLoader<RegisterCenter> 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, Set<ServiceInstance> 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的客户端依赖--><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>2.0.4</version></dependency><!--导入我们直接实现的注册中心接口--><dependency><groupId>blossom.project</groupId><artifactId>BlossomGateway-Register-Center-Api</artifactId><version>1.0</version></dependency></dependencies>

之后,我们就可以使用Nacos客户端中提供的服务注册方法进行服务注册了。
方式如下:


@Slf4j
public class NacosRegisterCenter implements RegisterCenter {/*** 注册中心的地址*/private String registerAddress;/*** 环境选择*/private String env;/*** 主要用于维护服务实例信息*/private NamingService namingService;/*** 主要用于维护服务定义信息*/private NamingMaintainService namingMaintainService;/*** 监听器列表* 这里由于监听器可能变更 会出现线程安全问题*/private List<RegisterCenterListener> 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了,所以这里可以直接拿到当前服务已经订阅的服务//如果不了解的可以debugSet<String> subscribeService =namingService.getSubscribeServices().stream().map(ServiceInfo::getName).collect(Collectors.toSet());int pageNo = 1;int pageSize = 100;//分页从nacos拿到所有的服务列表List<String> 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);//获取服务实例信息List<Instance> allInstances = namingService.getAllInstances(service.getName(), env);Set<ServiceInstance> 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注册中心发生信息变更的时候,能在一次拉取到最新的配置信息。也就是我们完成了对注册中心的订阅。

相关文章:

【从0到1设计一个网关】整合Nacos-服务注册与服务订阅的实现

文章目录 Nacos定义服务注册与订阅方法服务信息加载与配置实现将网关注册到注册中心实现服务的订阅 Nacos Nacos提供了许多强大的功能&#xff1a; 比如服务发现、健康检测。 Nacos支持基于DNS和基于RPC的服务发现。 同时Nacos提供对服务的实时的健康检查&#xff0c;阻止向不…...

【uniapp】短信验证码输入框

需求是短信验证码需要格子输入框 如图 网上找了一个案例改吧改吧 直接上代码 结构 <template><view class"verify-code"><!-- 输入框 --><input id"input" :value"code" class"input" :focus"isFocus"…...

负载均衡的综合部署练习(hproxy+keepalived和lvs-DR+keepalived+nginx+Tomcat)

一、haproxykeepalived haproxy 2台 20.0.0.21 20.0.0.22 nginx 2台 20.0.0.23 20.0.0.24 客户机 1台 20.0.0.30 这里没有haproxy不是集群的概念&#xff0c;他只是代理服务器。 访问他直接可以直接访问后端服务器 关闭防火墙 安装haproxy和环境&#xff1a; yum in…...

设计模式——策略模式(Strategy Pattern)+ Spring相关源码

文章目录 一、策略模式定义二、例子1. 菜鸟教程例子&#xff08;略有改动&#xff09;1.1 、定义。1.2、定义加法策略类1.3、定义乘法策略类1.4、创建 Context 类1.5、使用 2、JDK awt包——BufferStrategy3、Spring源码 —— InstantiatorStrategy4、Spring源码 —— Instanti…...

ORB-SLAM3算法2之开源数据集运行ORB-SLAM3生成轨迹并用evo工具评估轨迹

文章目录 0 引言1 数据和真值1.1 TUM1.2 EuRoc1.3 KITTI2 ORB-SLAM3的EuRoc示例3 ORB-SLAM3的TUM-VI示例4 ORB-SLAM3的ROS各版本示例4.1 单目4.2 单目和IMU4.3 双目4.4 双目和IMU4.5 RGB-D0 引言 ORB-SLAM3算法1 已成功编译安装ORB-SLAM3到本地,本篇目的是用TUM、EuRoc和KITT…...

Qt 序列化函数和反序列化函数

文章目录 界面学生类序列化函数反序列化函数刷新所选择的下拉表值添加 界面 学生类 // 创建学生信息类 class studentInfo { public:QString id; // 学号QString name; // 学生姓名QString age; // 学生年龄// 重写QDataStream& operator<<操作符&…...

Linux之线程池

线程池 线程池概念线程池的应用场景线程池实现原理单例模式下线程池实现STL、智能指针和线程安全其他常见的各种锁 线程池概念 线程池&#xff1a;一种线程使用模式。 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待…...

MAC安装stable diffusion

./webui.sh --precision full --no-half-vae --disable-nan-check --api Command: "/Users/xxxx/aigc/stable-diffusion-webui/venv/bin/python3" -m pip install torch2.0.1 torchvision0.15.2 Error code: 2 执行命令&#xff1a; pip install torch2.0.1 torchvi…...

FPGA_状态机工作原理

FPGA_状态机介绍和工作原理 状态机工作原理Mealy 状态机模型Moore 状态机模型状态机描述方式代码格式 总结 状态机工作原理 状态机全称是有限状态机&#xff08;Finite State Machine、FSM&#xff09;&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学…...

【python练习】python斐波那契数列超时问题

计算斐波那契数列第n项的数字 Description计算斐波那契数列第n项的数字&#xff0c;其中f(1)f(2)1,f(n)f(n-1)f(n-2)&#xff0c;如1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5,......Input 正整数n(n<100)Output 一个整数f(n)Sample Input 1 8 Sample Output 1…...

SpringCloud 微服务全栈体系(五)

第七章 Feign 远程调用 先来看我们以前利用 RestTemplate 发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; 代码可读性差&#xff0c;编程体验不统一 参数复杂 URL 难以维护 Feign 是一个声明式的 http 客户端&#xff0c;官方地址&#xff1a;https://github.…...

msvcp140.dll丢失的正确解决方法

在使用电脑中我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp140.dll丢失”。这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;我们需要采取一些措施来修复丢失的msvcp140.dll文件。本文将介绍6个不同的解决方法&#xff0c;帮助读者解决…...

go pprof 如何使用 --chatGPT

gpt: pprof 是 Go 语言的性能分析工具&#xff0c;它可以用来检测 CPU 使用情况、内存使用情况、以及阻塞情况。你可以使用 pprof 来帮助诊断程序的性能问题&#xff0c;包括内存泄漏。 以下是如何使用 pprof 来分析内存泄漏的基本步骤&#xff1a; 1. **导入 pprof 包**&am…...

大数据可视化BI分析工具Apache Superset实现公网远程访问

大数据可视化BI分析工具Apache Superset实现公网远程访问 文章目录 大数据可视化BI分析工具Apache Superset实现公网远程访问前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网…...

软考系统架构师知识点集锦二:软件工程

一、考情分析 二、考点精讲 2.1 软件过程模型 &#xff08;1&#xff09;原型模型 典型的原型开发方法模型。适用于需求不明确的场景,可以帮助用户明确需求。可以分为[抛弃型原型]与[演化型原型] 原型模型两个阶段: 1、原型开发阶段;2、目标软件开发阶段。 &#x…...

Go并发:使用sync.Pool来性能优化

简介 在Go提供如何实现对象的缓存池功能&#xff1f;常用一种实现方式是&#xff1a;sync.Pool, 其旨在缓存已分配但未使用的项目以供以后重用&#xff0c;从而减轻垃圾收集器&#xff08;GC&#xff09;的压力。 快速使用 sync.Pool的结构也比较简单&#xff0c;常用的方法…...

git stash的使用方法

git stash的使用方法 应用场景 当我们在开发一个新功能的时候&#xff0c;或者开发到一半&#xff0c;然后就收到了线上master 出现了bug&#xff0c;当分支开发已经进行了或者进行到一半了&#xff0c;这时怎么办呢&#xff1f; 这时解决方案有两种&#xff1a;一种是先先将当…...

【影刀演示_发送邮件的格式化HTML留存】

发送邮件的格式化HTML留存 纯文本&#xff1a; 亲爱的小张: 端午节将至&#xff0c;公司为了感谢大家一年以来的辛勤工作和付出&#xff0c;特别为大家准备了京客隆超市福利卡&#xff0c;希望为大家带来些许便利和节日的喜悦。 以下是您的福利卡卡号和密码&#xff0c;请您…...

深度学习(4)---生成式对抗网络(GAN)

文章目录 一、原理讲述1.1 概念讲解1.2 生成模型和判别模型 二、训练过程2.1 训练原理2.2 损失函数 三、应用 一、原理讲述 1.1 概念讲解 1. 生成式对抗网络&#xff08;Generative Adversarial Network&#xff0c;GAN&#xff09;是一种深度学习模型&#xff0c;是近年来复杂…...

ThinkPad电脑HDMI接口失灵如何解决?

ThinkPad电脑HDMI接口失灵如何解决&#xff1f; 如果平时正常使用的外接显示器&#xff0c;某天突然无法使用了&#xff0c;重新插拔依然无信号的话&#xff0c;可以打开系统的设备管理器&#xff08;快捷键winx&#xff09;&#xff0c;首先看一下监视器的识别情况&#xff0c…...

第四部分:JavaScript

一&#xff1a;jQuery 1.1&#xff1a;jQuery介绍 什么是jQuery&#xff1f; jQuery是JavaScript和查询&#xff08;Query&#xff09;&#xff0c;它是辅助JavaScript开发的js类库 jQuery的核心思想 核心思想是write less&#xff0c;do more&#xff0c;所以它实现了很多浏览…...

【游戏开发】【心法】游戏设计心法系列1-以玩法为核心去设计游戏

游戏的本质 游戏的魔法在于寻找隐藏事物之间的联系。 游戏的魅力在于随着玩家逐渐发现并了解游戏世界的方方面面&#xff0c;他会得到一种丰富而深厚的体验。 挑战&#xff0c;竞争和互动是游戏玩法的三大要素。 规则&#xff0c;过程&#xff0c;目标则是游戏内容的要素。 如…...

chrome谷歌浏览器取消网页所有剪切板的授权方法步骤

地址栏输入 chrome://settings/content/clipboard选择 不允许网站查看您剪贴板中的文字或图片 ———————————————— 版权声明&#xff1a;本文为CSDN博主「一切V随缘」的原创文章&#xff0c;遵循CC 4.0 BY-SA版权协议&#xff0c;转载请附上原文出处链接及本声明…...

目标检测算法改进系列之嵌入Deformable ConvNets v2 (DCNv2)

Deformable ConvNets v2 简介&#xff1a;由于构造卷积神经网络所用的模块中几何结构是固定的&#xff0c;其几何变换建模的能力本质上是有限的。在DCN v1中引入了两种新的模块来提高卷积神经网络对变换的建模能力&#xff0c;即可变形卷积 (deformable convolution) 和可变形…...

最新发布!阿里云卓越架构框架重磅升级

云布道师 10 月 19 日阿里云峰会山东上&#xff0c;阿里云重磅升级《阿里云卓越架构白皮书》&#xff0c;助力企业在阿里云上构建更加安全、高效、稳定的云架构。《阿里云卓越架构白皮书》在今年的阿里云峰会粤港澳大湾区首度亮相&#xff0c;这是阿里云基于多年服务各行各业客…...

如何监听/抓取两个设备/芯片之间“UART串口”通信数据--监视TXD和RXD

案例背景&#xff1a;全网仅此一篇&#xff01;&#xff01;&#xff01; 两个设备/芯片之间采用UART串口通信。我们如何实现芯片1 TXD – > 芯片2 RXD&#xff0c;芯片2 TXD --> 芯片1 RXD两个单线链路上的数据抓取和监听&#xff1f;这篇博客将告诉您。 目录 1 什么是…...

JDK项目分析的经验分享

基本类型的包装类(Character放在最后) String、StringBuffer、StringBuilder、StringJoiner、StringTokenizer(补充正则表达式的知识) CharacterIterator、StringCharacterIterator、CharsetProvider、CharsetEncoder、CharsetDecoder(较难) java.util.function下的函数表…...

Java创建一个长度为10的数组,利用Arrays.sort(), 为数组元素排序

程序要求&#xff1a;1&#xff09;创建一个整型数组&#xff0c;数组的长度为10. 2&#xff09;给数组元素赋值&#xff0c;要求乱序。 3&#xff09;利用fori循环将数组元素依次输出。 4&#xff09;利用Arrays.sort(), 为数组元素排序 5&#xff09;采用增加for循环将排…...

python 动态加载C# 动态库的一些问题

python导入C#动态库问题 背景介绍 我使用的python是3.7&#xff0c;需要调用之前已经用于其他项目的C#编写的动态库(xx.dll).由于调用方法很简单&#xff0c;可以参考下这个调用动态库,这里主要说一下我遇到的问题。 试图加载格式不正确的程序 这个问题实际是由于目标程序和…...

代码审计-锐捷NBR路由器 EWEB网管系统 远程命令执行

那天下着很大的雨&#xff0c;母亲从城里走回来的时候&#xff0c;浑身就是一个泥人&#xff0c;那一刻我就知道我没有别的选择了 出现漏洞的文件在 /guest_auth/guestIsUp.php 审查源码我们发现通过命令拼接的方式构造命令执行 构造payload&#xff1a; /guest_auth/guestI…...