首页 文章 精选 留言 我的

精选列表

搜索[工企 AI],共10000篇文章
优秀的个人博客,低调大师

中科院与厦合作 建智慧城市实验室

15日下午,中国科学院上海产业技术创新与育成中心和厦门唐人科技股份有限公司签署战略合作协议,决定成立智慧城市联合实验室并举行揭牌仪式。实验室旨在推动以互联网+、云计算、物联网为代表的信息技术与智慧城市、智慧楼宇应用的深入融合,建设以数据化、智能化为主要特征和多业态建筑环境下的智慧城市。 实验室的组建,实现“产学研”强强联合,今后将成为中国科学院与厦门唐人科技股份有限公司乃至厦门科技企业中间的一个桥梁,将中科院的研究成果结合市场需求的具体情况进行推广,公司则根据实验室的成果进行落地实施,使智慧城市高端的理论研究能迅速地转化为市场需求的成果。同时公司也可将客户所需的智慧城市有关项目提交给实验室,与中科院联合进行研究开发。 本文转自d1net(转载)

优秀的个人博客,低调大师

【曹杂谈】说说Maven框架和插件的契约

说说Maven框架和插件的契约 前言 Maven框架就像现在公司内的各种平台方,规定一些契约,然后想办法拉动业务方,一起在这个平台上去做生态共建。Maven也是这样,其实它就是一个插件执行的框架,Maven刚开始肯定不知道会有谁去贡献插件,插件如果写得五花八门的话,那对于平台方来说,可能就是一个灾难,所以,平台方就要负责定标准,要在我平台上写插件,必须怎么怎么样。 Maven给插件就定了契约,这个契约,是通过api jar包的方式。每次发布Maven新版本,与之伴随的,都会有一个api jar包。 如果有人要基于这个版本的api jar包来开发插件,就需要把这个插件引入到自己的插件工程中。然后根据api jar包中的契约接口,来实现自己的插件逻辑。 比如,maven clean插件的工程代码中,就依赖了api jar包。如下: api jar包中的契约接口长啥样呢? public interface Mojo { ... void execute() throws MojoExecutionException, MojoFailureException; } 核心方法就是这个,只要你实现这个接口就完事了。 作为框架方,怎么去调用这个插件呢?简而言之,就是: 1、找到插件的实现类jar包,然后构造一个该插件的类加载器,去加载这个jar包,然后找到对应的实现了契约接口的类,比如这里的CleanMojo 2、加载了这个CleanMojo的class之后,当然是反射生成对象,然后强制转换为契约接口,然后调用契约接口就行。比如: Class cleanMojoClass = 插件的类加载器加载插件的jar包; Mojo cleanMojo = (Mojo)cleanMojoClass.newInstance(); cleanMojo.execute(); 到此为止,我们的理论知识已经足够了,我们是不是可以show the code了? 工程实践 我们会模拟上面的过程, 建一个Maven module,用来存放插件api契约接口; 建一个Maven module,引入api,实现插件api,这样,我们的插件就算是实现好了; 接下来,把这两个工程编译一下,把jar包安装到本地仓库; 再新建一个工程,模拟Maven框架去加载插件,并执行插件。 插件api工程 直接用maven的archetype中的quickstart,新建一个module,里面很简单,就一个接口: 然后执行mvn install,安装到本地仓库。 插件实现工程 在pom中,我们会引入api。 <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>my-plugin-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> 代码也很简单,就一个实现类。 然后执行mvn install,安装到本地仓库。 主工程,模拟框架去调用插件 主工程就是模拟我们的Maven框架,由于我们调用插件,肯定是通过api的方式,所以,pom中肯定是要引入api的。 <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>my-plugin-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> 接下来,我们写了个测试类: public static void main( String[] args ) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException { // 1.1处 URL urlForPluginApi = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-api\\1.0-SNAPSHOT\\my-plugin-api-1.0-SNAPSHOT.jar"); URL urlForPluginImpl = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-implementation\\1.0-SNAPSHOT\\my-plugin-implementation-1.0-SNAPSHOT.jar"); URL[] urls = {urlForPluginApi, urlForPluginImpl}; // 1.2 URLClassLoader urlClassLoader = new URLClassLoader(urls,ClassLoader.getSystemClassLoader()){ @Override public Class<?> loadClass(String name) throws ClassNotFoundException { try{ // 保证:寻找类时,优先查找自己的classpath,找不到,再去交给parent classloader Class<?> clazz = findClass(name); return clazz; }catch (ClassNotFoundException exception ){ return super.loadClass(name); } } }; // 1.3 Class<?> implClazzByPluginClassloader = urlClassLoader.loadClass("org.example.MyMojoImplementation"); // 1.4 MojoInterface mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance(); // 1.5 mojoInterface.execute(); System.out.println( "Hello World!" ); } 我先大概讲解一下上述代码: 1.1处,构造了两个url,分别指向我本地仓库的两个文件,也就是api.jar和插件对应的实现的jar 1.2处,使用1.1中的url,构造了一个classloader,这个classloader的parent classloader,我们传的是,系统的AppClassloader。 同时,我们重写了这个classloader的行为,重写后的行为如下:遇到要加载的类时,自己优先加载,也就是会去自己的两个url里面找,看看能不能找到,如果找不到,就会进入异常,异常被我们捕获后,交给parent classloader去加载; 1.3处,我们用新建的classloader,去加载了插件的实现类 1.4处,利用1.3处加载的实现类的class,反射生成对象,强转为MojoInterface接口对象 1.5处,多态方式执行插件逻辑 大家不妨思考下,大家觉得,最终的执行结果是啥?我们的“hello world”能打印出来吗? 这个代码,我们上传了gitee,大家可以拉下来看。 https://gitee.com/ckl111/maven-3.8.1-source-learn 我这边给大家展示下,执行结果: 大家看看,这像话吗,明明我的插件代码里,是实现了接口的,怎么就不能向上转型呢?: public class MyMojoImplementation implements MojoInterface{ @Override public void execute() { System.out.println("implementation execute business logic"); } } 这个。。。怎么说呢。。。这么跟你解释吧,我们加载MyMojoImplementation时,发现这个类吧,还实现了接口MojoInterface,那么,这个接口类也就需要加载,因为我们classloader进行了改写(优先由自己进行加载),因此,最终呢,MojoInterface也就和MyMojoImplementation一样,都是由插件类加载器去加载的。 最终呢,在向上转型时,会出现下边这个情况,两边不匹配,就报错了。 MojoInterface(框架中的这个类,是由框架的类加载器加载的) mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance();(这个实现类实现的接口,是由插件类加载器加载的) 课后题 我们对代码进行了修改,改成了如下的样子,结果,就可以跑通我们的hello world了。这又是为啥呢? 我是逐日, 深圳腾讯打工人,成都深圳两地反复横跳的后端java程序猿一枚. 之前在深圳3年,后来去了成都4年,现在又来了深圳,也开始写写前端,有需要内推的可以找我。对于一线编码实战、网络、数据库、高并发等有浓厚兴趣。 也欢迎加我,拉进技术群一起交流;腾讯内推也可以找我。 本文由博客一文多发平台 OpenWrite 发布!

优秀的个人博客,低调大师

在路上--一文弄懂MSTP协议

对于STP生成树协议,了解的人比较多。通过STP协议,解决了二层网络内的环路问题,在消除环路和链路备份之间达成了平衡。但在现网中,一个二层网路内往往不止一个vlan,而是多个vlan的集合,STP/RSTP只能处理单个vlan的问题,而对于多个vlan的情况束手无策。因此,MSTP的出现至关重要。本文通过查询华为Hex文档,结合自身理解,形成比较清晰而重要的MSTP的文档,可能是全网最详细的MSTP文档。 1 定义 MSTP(multiple spanning tree protocol)是多生成树协议,通过生成多个生成树,来解决以太网的环路问题。 2 目的 在一个局域网内生成多个STP树,解决多个vlan的广播风暴,并实现冗余备份。 多棵STP树在vlan间实现负载均衡,不同vlan的流量按照不同的路径转发。解决stp/rstp某一vlan的链路被阻塞后所有vlan均被阻塞的问题。在此图中,如果在全网内应用stp/rstp,则按协议要求,得到一棵用虚线表示的生成树,其中,S6为根桥,S2和S5之间、S1和S4之间的链路被阻塞。如果该网中只有一种vlan或者vlan的允许通过的链路一样,则stp/rstp已经满足现网要求。但是由于s1和s2之间,s3和s6之间只允许vlan3通过,s4与s5之间只允许vlan2通过,所以hostB和hostA之间无法通信。因此需要MSTP协议的引入来解决这种问题。 3 原理 MSTP把一个交换网络划分成多个域,每个域形成多棵生成树,生成树之间彼此独立,每颗生成树叫做一个多生成树实例MSTI(multiple spanning tree instance),每个域叫做一个MST域(multiple spanning tree region)。每个MSTI可以看作是多个vlan的集合,即vlan根据需要捆绑在若干MSTI上(一般而言,这种需要指的是相同的拓扑结构),vlan和MSTI是多对一的关系,这样可以节省通信开销和资源占用率。在引入MSTP后,MSTP通过设置vlan映射表,把vlan和msti联系起来,根据现网需要,该网络中,每个vlan对应了一个msti。可以认为,每个msti之间允许独立的stp协议。经过计算,最终生成了两棵树: MSTI1 以 S4为根交换设备,转发VLAN 2 的报文 MSTI2 以S6 为根交换设备,转发VLAN 3 的报文以往我们认为,一个交换网络中只会存在一个根桥,但是在引入MSTP后,交换网络中可以存在多个根桥,根桥数量与MSTI的数量一致。 4 基本概念 4.1 网络层次 一个MSTP网络中包含多个MST域,每个MST域中包含多个MSTI,一个MSTI中包含多个运行STP/RSTP/MSTP的交换设备 4.2 MST域 MST域由交换网络中的多台交换设备以及他们之间的网段所组成。同一MST域的设备具有以下特点: 都启用了MSTP 具有相同的域名 (region name) 相同的vlan-MSTI映射关系 (instance xx vlan xx) 相同的MSTP修订级别配置(region level) MST域之间在物理上直接或者间接相连。 4.3 VLAN映射表 描述了vlan和MSTI的映射关系,vlan和MSTI是多对一的关系。 4.4 CST 公共生成树,连接交换网络内所有MST域的一棵生成树。如果把MST域看作是一个节点或桥,那么CST就是这些节点通过STP/RSTP计算生成的一棵生成树。 4.5 CIST&IST CIST是公共和内部生成树,通过STP/RSTP生成,将交换网内所有交换设备看作是没有vlan区分的设备,由它们生成一棵单生成树。 IST是内部生成树,是MST域内的一棵生成树,IST是一个特殊的MSTI,MSTI的ID为0,通常称为MSTI0。可以把IST理解成CIST在MST域内的一个子集。 4.6 SST 单生成树,运行STP/RSTP的交换设备只能属于一个生成树。或者MST域中只有一个交换设备,这个交换设备构成单生成树。 4.7 总根&域根 总根是CIST的根桥。 域根分为IST域根和MSTI域根。 IST域根是在MST域中IST生成树中距离总根最近的交换设备。 MSTI域根是每个多生成树实例的树根。一个MSTI域内可以有多个生成树实例,也即有多个MSTI域根。 4.8 主桥 IST Master,域内距离总根最近的交换设备。 5 端口角色 相比于RSTP,MSTP在根端口,指定端口,alternate端口,backup端口和边缘端口的基础上,新增master端口和域边缘端口。即共有7种端口类型。 5.1 master端口 是MST域和总根相连的所有路径种最短路径上的端口,是交换设备上连接MST域到总根的端口。Master端口是域中的报文去往总根的必经之路。master端口是特殊的域边缘端口,他在CIST上的角色是root port ,在其他各实例上的角色都是master端口。 5.2 域边缘端口 位于MST域的边缘并连接其他MST域或SST的端口。 6 MSTP报文格式 相比于RST BPDU报文,MSTP的BPDU报文前36字节是相同的。从第37字节开始是其专有字段。目前MST BPDU存在两种格式。分别是: dot1s legacy需要人工识别,手动配置,配错成环。华为新增:auto实现自动识别,自动适配。初始支持dot1s。 7 MSTP拓扑计算 MSTP将二层网络分为多个MST域,域间计算生产CST,域内分为多个生成树实例,每个实例分别计算独立的STP生成树。实例0被称为IST,其他的多生成树实例为MSTI。 7.1 优先级向量 MSTI的优先级向量{域根ID,内部路径开销,指定交换设备ID,指定端口ID,接收端口ID} CIST的优先级向量{根交换设备ID,外部路径开销,域根ID,内部路径开销,指定交换设备ID,指定端口ID,接收端口ID}从左至右依次递减。 向量名称 说明 根交换设备ID CIST的根交换设备ID,等于priority(16bit)+MAC(48bit),其中priority为MSTI0的优先级 外部路径开销(ERPC) 从CIST的域根到达总根的路径开销。MST域内所有交换设备上保存的外部路径开销相同。若CIST根交换设备在域中,则域内所有交换设备上保存的外部路径开销为0。 域根ID 域根ID用于选择MSTI中的域根。域根ID = Priority(16bits) + MAC(48bits)。其中Priority为MSTI0的优先级。 内部路径开销(IRPC) 本桥到达域根的路径开销。域边缘端口保存的内部路径开销大于非域边缘端口保存的内部路径开销。 指定交换设备ID CIST或MSTI实例的指定交换设备是本桥通往域根的最邻近的上游桥。如果本桥就是总根或域根,则指定交换设备为自己。 指定端口ID 指定交换设备上同本设备上根端口相连的端口。Port ID = Priority(4位) + 端口号(12位)。端口优先级必须是16的整数倍。 接收端口ID 接收到BPDU报文的端口。Port ID = Priority(4位) + 端口号(12位)。端口优先级必须是16的整数倍。 7.2 比较原则 同一向量比较,值最小的向量具有最高优先级。 1 比较根交换设备ID。 2 如果根交换设备ID相同,再比较外部路径开销。 3 如果外部路径开销相同,再比较域根ID。 4 如果域根ID仍然相同,再比较内部路径开销。 5 如果内部路径仍然相同,再比较指定交换设备ID。 6 如果指定交换设备ID仍然相同,再比较指定端口ID。 7 如果指定端口ID还相同,再比较接收端口ID。 如果端口接收到的BPDU内包含的配置消息优于端口上保存的配置消息,则端口上原来保存的配置消息被新收到的配置消息替代。端口同时更新交换设备保存的全局配置消息。反之,新收到的BPDU被丢弃。 7.3 CIST的计算 经过比较配置消息后,在整个网络中选择一个优先级最高的交换设备作为CIST的树根。在每个MST域内MSTP通过计算生成IST;同时MSTP将每个MST域作为单台交换设备对待,通过计算在MST域间生成CST。CST和IST构成了整个交换设备网络的CIST。 7.4 MSTI的计算 在MST域内,MSTP根据VLAN和生成树实例的映射关系,针对不同的VLAN生成不同的生成树实例。每棵生成树独立进行计算,计算过程与STP计算生成树的过程类似 MSTI的特点: 每个MSTI独立计算自己的生成树,互不干扰。 每个MSTI的生成树计算方法与STP基本相同。 每个MSTI的生成树可以有不同的根,不同的拓扑。 每个MSTI在自己的生成树内发送BPDU。 每个MSTI的拓扑通过命令配置决定。 每个端口在不同MSTI上的生成树参数可以不同。 每个端口在不同MSTI上的角色、状态可以不同。 在运行MSTP协议的网络中,一个VLAN报文将沿着如下路径进行转发: 在MST域内,沿着其对应的MSTI转发。 在MST域间,沿着CST转发。 8 MSTP快速收敛机制(P/A机制) 8.1 普通方式 -1 p0和p1两个端口马上都先成为指定端口,发送RST BPDU。-2 S2的p1口收到更优的RST BPDU,马上意识到自己将成为根端口,而不是指定端口,停止发送RST BPDU。 3 S1的p0进入Discarding状态,于是发送的RST BPDU中把proposal和Agreement置1。 4 S2收到根桥发送来的携带proposal的RST BPDU,开始将自己的所有端口进入sync变量置位。 5 p2已经阻塞,状态不变;p4是边缘端口,不参与运算;所以只需要阻塞非边缘指定端口p3。 6 各端口的synced变量置位后,p2、p3进入Discarding状态,p1进入Forwarding状态并向S1返回Agreement位置位的回应RST BPDU。 7 当S1判断出这是对刚刚发出的Proposal的回应,于是端口p0马上进入Forwarding状态。下游设备继续执行P/A协商过程。 8.2 增强方式 1 协商开始时,每一台设备都认为自己是根桥,根桥上的端口是指定端口,端口状态为Discarding,端口的synced变量置位,触发Proposal和Agreement同时置位。上游设备发送Proposal报文,请求进行快速迁移。下游设备接收到后,把与上游设备相连的端口设置为根端口,并阻塞所有非边缘端口。 2 上游设备继续发送Agreement报文。下游设备接收到后,根端口转为Forwarding状态。 3 下游设备回应Agreement报文。上游设备接收到后,把与下游设备相连的端口设置为指定端口,指定端口进入Forwarding状态。 缺省情况下,华为数据通信设备使用增强的快速迁移机制。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册