那些年,我们见过的Java服务端“问题”

明代著名的心学集大成者王阳明先生在《传习录》中有云:

道无精粗,人之所见有精粗。如这一间房,人初进来,只见一个大规模如此。处久,便柱壁之类,一一看得明白。再久,如柱上有些文藻,细细都看出来。然只是一间房。

是的,知识理论哪有什么精粗之分,只是人的认识程度不同而已。笔者在初创公司摸爬滚打数年,接触了各式各样的Java服务端架构,见得多了自然也就认识深了,就能分辨出各种方案的优劣了。这里,笔者总结了一些初创公司存在的Java服务端问题,并尝试性地给出了一些不成熟的解决方案。

随着互联网的发展,计算机系统早就从单机独立工作过渡到多机器协同工作。计算机以集群的方式存在,按照分布式理论构建出庞大复杂的应用服务,早已深入人心并得到广泛地应用。但是,仍然有不少创业公司的软件系统停留在"单机版"。

这里,用并发性比较高的抢单功能为例说明:

//抢取订单函数publicsynchronizedvoidgrabOrder(LongorderId,LonguserId){//获取订单信息OrderDOorder=orderDAO.get(orderId);if(Objects.isNull(order)){thrownewBizRuntimeException(String.format("订单(%s)不存在",orderId));}//检查订单状态if(!Objects.equals(order.getStatus,OrderStatus.WAITING_TO_GRAB.getValue())){thrownewBizRuntimeException(String.format("订单(%s)已被抢",orderId));}//设置订单被抢orderDAO.setGrabed(orderId,userId);}以上代码,在一台服务器上运行没有任何问题。进入函数grabOrder(抢取订单)时,利用synchronized关键字把整个函数锁定,要么进入函数前订单未被人抢取从而抢取订单成功,要么进入函数前订单已被抢取导致抢取订单失败,绝对不会出现进入函数前订单未被抢取而进入函数后订单又被抢取的情况。

但是,如果上面的代码在两台服务器上同时运行,由于Java的synchronized关键字只在一个虚拟机内生效,所以就会导致两个人能够同时抢取一个订单,但会以最后一个写入数据库的数据为准。所以,大多数的单机版系统,是无法作为分布式系统运行的。

添加分布式锁,进行代码优化:

//抢取订单函数publicvoidgrabOrder(LongorderId,LonguserId){LonglockId=orderDistributedLock.lock(orderId);try{grabOrderWithoutLock(orderId,userId);}finally{orderDistributedLock.unlock(orderId,lockId);}}//不带锁的抢取订单函数privatevoidgrabOrderWithoutLock(LongorderId,LonguserId){//获取订单信息OrderDOorder=orderDAO.get(orderId);if(Objects.isNull(order)){thrownewBizRuntimeException(String.format("订单(%s)不存在",orderId));}//检查订单状态if(!Objects.equals(order.getStatus,OrderStatus.WAITING_TO_GRAB.getValue())){thrownewBizRuntimeException(String.format("订单(%s)已被抢",orderId));}//设置订单被抢orderDAO.setGrabed(orderId,userId);}优化后的代码,在调用函数grabOrderWithoutLock(不带锁的抢取订单)前后,利用分布式锁orderDistributedLock(订单分布式锁)进行加锁和释放锁,跟单机版的synchronized关键字加锁效果基本一样。

分布式系统(DistributedSystem)是支持分布式处理的软件系统,是由通信网络互联的多处理机体系结构上执行任务的系统,包括分布式操作系统、分布式程序设计语言及其编译系统、分布式文件系统分布式数据库系统等。

分布式系统的优点:

一台服务器的崩溃,不会影响其它服务器,其它服务器仍能提供服务。

如果系统服务能力不足,可以水平扩展更多服务器。

可以很容易的安装、实施、扩容和升级系统。

拥有多台服务器的计算能力,比单台服务器处理速度更快。

分布式系统对服务器硬件要求很低,可以选用廉价服务器搭建分布式集群,从而得到更好的性价比。

分布式系统的缺点:

由于系统分布在多台服务器上,故障排查和问题诊断难度较高。

分布式系统解决方案的软件支持较少。

需要多台服务器搭建分布式系统。

曾经有不少的朋友咨询我:"找外包做移动应用,需要注意哪些事项?"

其次,确定是否真正的分布式系统。分布式系统最大的特点,就是当系统服务能力不足时,能够通过水平扩展的方式,通过增加服务器来增加服务能力。然而,单机版系统是不支持水平扩展的,强行扩展就会引起一系列数据问题。由于单机版系统和分布式系统的研发成本差别较大,市面上的外包团队大多用单机版系统代替分布式系统交付。那么,如何确定你的系统是真正意义上的分布式系统呢?从软件上来说,是否采用了分布式软件解决方案;从硬件上来说,是否采用了分布式硬件部署方案。

作为一个合格的分布式系统,需要根据实际需求采用相应的分布式软件解决方案。

分布式锁是单机锁的一种扩展,主要是为了锁住分布式系统中的物理块或逻辑块,用以此保证不同服务之间的逻辑和数据的一致性。

目前,主流的分布式锁实现方式有3种:

分布式消息中间件是支持在分布式系统中发送和接受消息的软件基础设施。常见的分布式消息中间件有ActiveMQ、RabbitMQ、Kafka、MetaQ等。

MetaQ(全称Metamorphosis)是一个高性能、高可用、可扩展的分布式消息中间件,思路起源于LinkedIn的Kafka,但并不是Kafka的一个拷贝。MetaQ具有消息存储顺序写、吞吐量大和支持本地和XA事务等特性,适用于大吞吐量、顺序消息、广播和日志数据传输等场景。

针对大数据量的数据库,一般会采用"分片分组"策略:

分片(shard):主要解决扩展性问题,属于水平拆分。引入分片,就引入了数据路由和分区键的概念。其中,分表解决的是数据量过大的问题,分库解决的是数据库性能瓶颈的问题。

分组(group):主要解决可用性问题,通过主从复制的方式实现,并提供读写分离策略用以提高数据库性能。

分布式计算(Distributedcomputing)是一种"把需要进行大量计算的工程数据分割成小块,由多台计算机分别计算;在上传运算结果后,将结果统一合并得出数据结论"的科学。

当前的高性能服务器在处理海量数据时,其计算能力、内存容量等指标都远远无法达到要求。在大数据时代,工程师采用廉价的服务器组成分布式服务集群,以集群协作的方式完成海量数据的处理,从而解决单台服务器在计算与存储上的瓶颈。Hadoop、Storm以及Spark是常用的分布式计算中间件,Hadoop是对非实时数据做批量处理的中间件,Storm和Spark是对实时数据做流式处理的中间件。

除此之外,还有更多的分布式软件解决方案,这里就不再一一介绍了。

介绍完服务端的分布式软件解决方案,就不得不介绍一下服务端的分布式硬件部署方案。这里,只画出了服务端常见的接口服务器、MySQL数据库、Redis缓存,而忽略了其它的云存储服务、消息队列服务、日志系统服务……

架构说明:

只有1台接口服务器、1个MySQL数据库、1个可选Redis缓存,可能都部署在同一台服务器上。

适用范围:

适用于演示环境、测试环境以及不怕宕机且日PV在5万以内的小型商业应用。

通过SLB/Nginx组成一个负载均衡的接口服务器集群,MySQL数据库和Redis缓存采用了一主一备(或多备)的部署方式。

适用于日PV在500万以内的中小型商业应用。

通过SLB/Nginx组成一个负载均衡的接口服务器集群,利用分片分组策略组成一个MySQL数据库集群和Redis缓存集群。

适用于日PV在500万以上的大型商业应用。

多线程最主要目的就是"最大限度地利用CPU资源",可以把串行过程变成并行过程,从而提高了程序的执行效率。

通过分析发现,绑定优惠券(bindCoupon)函数可以异步执行。首先想到的是采用多线程解决该问题,代码如下:

消息生产者代码:

//创建新用户函数privateUserVOcreateNewUser(StringphoneNumber){//创建新用户UserDOuser=newUserDO();...userDAO.insert(user);//发送优惠券消息LonguserId=user.getId();CouponMessageDataVOdata=newCouponMessageDataVO();data.setUserId(userId);data.setCouponType(CouponType.NEW_USER);Messagemessage=newMessage(TOPIC,TAG,userId,JSON.toJSONBytes(data));SendResultresult=metaqTemplate.sendMessage(message);if(!Objects.equals(result,SendStatus.SEND_OK)){log.error("发送用户({})绑定优惠券消息失败:{}",userId,JSON.toJSONString(result));}//返回新用户returntransUser(user);}注意:可能出现发生消息不成功,但是这种概率相对较低。

消息消费者代码:

//优惠券服务类@Slf4j@ServicepublicclassCouponServiceextendsDefaultMessageListener{//消息处理函数@Override@Transactional(rollbackFor=Exception.class)publicvoidonReceiveMessages(MetaqMessagemessage){//获取消息体Stringbody=message.getBody();if(StringUtils.isBlank(body)){log.warn("获取消息({})体为空",message.getId());return;}//解析消息数据CouponMessageDataVOdata=JSON.parseObject(body,CouponMessageDataVO.class);if(Objects.isNull(data)){log.warn("解析消息({})体为空",message.getId());return;}//绑定优惠券bindCoupon(data.getUserId(),data.getCouponType());}}解决方案优点:

采集MetaQ消息队列优化慢接口解决方案的优点:

这是一个简易的采购流程,由库管系统发起采购,采购员开始采购,采购员完成采购,同时回流采集订单到库管系统。

其中,完成采购动作的核心代码如下:

通过需求分析,把"采购员完成采购并回流采集订单"动作拆分为"采购员完成采购"和"回流采集订单"两个独立的动作,把"采购完成"拆分为"采购完成"和"回流完成"两个独立的状态,更方便采购流程的管理和实现。

拆分采购流程的动作和状态后,核心代码如下:

有限状态机(Finite-statemachine,FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的一个数学模型。

状态机可归纳为4个要素:现态、条件、动作、次态。

现态:指当前流程所处的状态,包括起始、中间、终结状态。

条件:也可称为事件;当一个条件被满足时,将会触发一个动作并执行一次状态的迁移。

动作:当条件满足后要执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。

次态:当条件满足后要迁往的状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

状态表示流程中的持久状态,流程图上的每一个圈代表一个状态。

初始状态:流程开始时的某一状态;

中间状态:流程中间过程的某一状态;

终结状态:流程完成时的某一状态。

使用建议:

动作的三要素:角色、现态、次态,流程图上的每一条线代表一个动作。

角色:谁发起的这个操作,可以是用户、定时任务等;

现态:触发动作时当前的状态,是执行动作的前提条件;

次态:完成动作后达到的状态,是执行动作的最终目标。

在一些项目中,系统间交互不通过接口调用和消息队列,而是通过数据库直接访问。问其原因,回答道:"项目工期太紧张,直接访问数据库,简单又快捷"。

还是以上面的采购流程为例——采购订单由库管系统发起,由采购系统负责采购,采购完成后通知库管系统,库管系统进入入库操作。采购系统采购完成后,通知库管系统数据库的代码如下:

/**执行回流动作函数(此处省去获取采购单/验证状态/锁定采购单等逻辑)*/publicvoidexecuteBackflow(PurchaseOrderorder){//完成原始采购单rawPurchaseOrderDAO.setStatus(order.getRawId(),RawPurchaseOrderStatus.FINISHED.getValue());//设置回流状态purchaseOrderDAO.setStatus(order.getId(),PurchaseOrderStatus.BACKFLOWED.getValue());}其中,通过rawPurchaseOrderDAO(原始采购单DAO)直接访问库管系统的数据库表,并设置原始采购单状态为已完成。

一般情况下,直接通过数据访问的方式是不会有问题的。但是,一旦发生竞态,就会导致数据不同步。有人会说,可以考虑使用同一分布式锁解决该问题。是的,这种解决方案没有问题,只是又在系统间共享了分布式锁。

直接通过数据库交互的缺点:

由于采购系统和库管系统都是内部系统,可以通过类似Dubbo的RPC接口进行交互。

库管系统代码:

采购系统代码:

/**执行回流动作函数(此处省去获取采购单/验证状态/锁定采购单等逻辑)*/publicvoidexecuteBackflow(PurchaseOrderorder){//完成采购单purchaseOrderService.finishPurchaseOrder(order.getRawId());//设置回流状态purchaseOrderDAO.setStatus(order.getId(),PurchaseOrderStatus.BACKFLOWED.getValue());}其中,purchaseOrderService(采购单服务)为库管系统PurchaseOrderService(采购单服务)在采购系统中的Dubbo服务客户端存根,通过该服务调用库管系统的服务接口函数finishPurchaseOrder(完成采购单函数)。

这样,采购系统和库管系统自己的强关联,通过Dubbo就简单地实现了系统隔离和解耦。当然,除了采用Dubbo接口外,还可以采用HTTPS、HSF、WebService等同步接口调用方式,也可以采用MetaQ等异步消息通知方式。

同步接口调用是以一种阻塞式的接口调用机制。常见的交互协议有:

异步消息通知是一种通知式的信息交互机制。当系统发生某种事件时,会主动通知相应的系统。常见的交互协议有:

适合于简单的耗时较短的接口同步调用场景,比如Dubbo接口同步调用。

适合于简单的异步消息通知场景,比如MetaQ消息通知。

适合于复杂的耗时较长的接口同步调用场景,比如提交作业任务并定期查询任务结果。

适合于复杂的耗时较长的接口同步调用和异步回调相结合的场景,比如支付宝的订单支付。

适合于复杂的耗时较长的接口同步调用和异步消息通知相结合的场景,比如提交作业任务并等待完成消息通知。

适合于复杂的耗时较长的异步消息通知场景。

在数据查询时,由于未能对未来数据量做出正确的预估,很多情况下都没有考虑数据的分页查询。

以下是查询过期订单的代码:

/**订单DAO接口*/publicinterfaceOrderDAO{/**查询过期订单函数*/@Select("select*fromt_orderwherestatus=5andgmt_createqueryTimeout();}/**订单服务接口*/publicinterfaceOrderService{/**查询过期订单函数*/publicListqueryTimeout();}当过期订单数量很少时,以上代码不会有任何问题。但是,当过期订单数量达到几十万上千万时,以上代码就会出现以下问题:

所以,在数据查询时,特别是不能预估数据量的大小时,需要考虑数据的分页查询。

这里,主要介绍"设置最大数量"和"采用分页查询"两种方式。

"设置最大数量"是一种最简单的分页查询,相当于只返回第一页数据。例子代码如下:

/**订单DAO接口*/publicinterfaceOrderDAO{/**查询过期订单函数*/@Select("select*fromt_orderwherestatus=5andgmt_createqueryTimeout(@Param("maxCount")IntegermaxCount);}/**订单服务接口*/publicinterfaceOrderService{/**查询过期订单函数*/publicListqueryTimeout(IntegermaxCount);}适用于没有分页需求、但又担心数据过多导致内存溢出、数据量过大的查询。

"采用分页查询"是指定startIndex(开始序号)和pageSize(页面大小)进行数据查询,或者指定pageIndex(分页序号)和pageSize(页面大小)进行数据查询。例子代码如下:

/**订单DAO接口*/publicinterfaceOrderDAO{/**统计过期订单函数*/@Select("selectcount(*)fromt_orderwherestatus=5andgmt_createqueryTimeout(@Param("startIndex")LongstartIndex,@Param("pageSize")IntegerpageSize);}/**订单服务接口*/publicinterfaceOrderService{/**查询过期订单函数*/publicPageDataqueryTimeout(LongstartIndex,IntegerpageSize);}适用于真正的分页查询,查询参数startIndex(开始序号)和pageSize(页面大小)可由调用方指定。

当满足查询条件的数据,在操作中不再满足查询条件时,会导致后续分页查询中前startIndex(开始序号)条满足条件的数据被跳过。

可以采用"设置最大数量"的方式解决,代码如下:

谨以此文献给当年"E代驾"下的"KK拼车"团队,怀念曾经一起奋斗过的兄弟们,怀念那段为代驾司机深夜返程保驾护航的岁月。深感遗憾的是,"KK拼车"刚刚崭露头角,还没来得及好好发展,就被公司断臂裁撤了。值得欣慰的是,"KK拼车"自在人心,据说现在已经成为了一个"民间组织"。

THE END
1.论文查看软件排行榜前十名偏玩手游盒子分享十大论文查看软件排行榜前十名手机应用,编辑为您推荐手机论文查看软件排行榜第一名到前5名到前十名的应用。找论文查看软件有哪些、论文查看软件哪个好用,上偏玩手游盒子https://m.pianwan.com/s/zj-1950188
2.大数据查询app有哪些?免费查大数据的软件大数据采集app下载大数据查询软件大全里面有小编为大家准备了一些可以查询大数据的手机数据采集和搜索的服务软件,软件卡里面包含了各个行业的详细数据和信息,让你可以在上百万条数据中找到你想要的信息或者通过这些信息去掌握市场动向,了解市场环境。软件功能分光伏,内容详细,有需要的用http://www.downyi.com/key/dashujuchaxunapp/
3.手机报告app推荐安卓报告软件有哪些现代社会,手机在我们的生活中充当着重要角色,就算是在工作上,也是显得越来越重要,大家开始在手机上去完成一些工作,各种邮件文件查看,移动办公,手机上看报告写报告也是大家在工作上会遇见的,今天小编给大家整理了一些好用的报告软件,各行各业类型的软件都有,支持大家在线写报告或是查看各种报告内容,需要的用户快来下载http://www.downcc.com/k/bgapp/
4.财源广进:这25个网站一定要收藏:1查婚史18、查旅游攻略——马蜂窝旅游网 19、查美食推荐——大众点评网 20、查房屋租售——贝壳找房 21、查装修灵感——好好住 22、查汽车信息——汽车之家 23、查手机数码产品——中关村在线 24、查体育赛事直播——腾讯体育、咪咕体育 25、查公开课资源——中国大学 MOOC 平台 。http://www.360doc.com/content/24/1211/09/16970701_1141693526.shtml
5.聚法案例下载安卓版聚法案例手机app官方下载最新版聚法案例安卓版是一款法律服务应用,聚法案例app为用户提供便捷的案例查询功能,可以帮助法律从业者快速查询案例,为用户学习法律带来帮助。华军软件园提供聚法案例app官方版下载地址,有需要的用户可免费下载使用! 聚法案例软件介绍 聚法案例提供优质的法律、案例检索服务,拥有最丰富的案例文库,是律师、学者、法官等法律人https://mip.onlinedown.net/soft/10042849.htm
6.人民法院案例库怎么用?人民法院案例库正式上线并向社会开放。 公众注册登录后就可以查阅。 人民法院案例库是什么? 入库案例有何标准? 一起来看看人民法院案例库的操作指南吧! 人民法院案例库互联网用户手册 一、如何快速查询案例? 图:简单检索 简单检索:在全部-全文下输入检索词,可以在指导性案例和参考https://mp.weixin.qq.com/s?__biz=MjM5MTI2ODYzMA==&mid=2447841343&idx=2&sn=b5d49fc470c00100b431cee73554c9cf&chksm=b2ab924685dc1b50061e15de650fb2c9fab715d0c11190393ee146ddce636b6afe94b63f6db2&scene=27
7.法律案例查询app法律案例平台有哪些法律案例搜索哪个app好?法律案例检索软件有哪些?小编为大家收集了一些专业实用的法律案例搜索软件,为大家提供多个领域的经典案件,以便大家能够更加方便的查阅相关资料,同时还覆盖其他功能,有需要就快来合集中下载吧!点击查看 资源列表 评论(0)其他法律推荐:法律服务离婚用的软件最新法律咨询可以查法律条文的app 律易搜http://m.5577.com/k/flal/
8.案例:程介村社区查询软件的安装案例:程介村社区查询软件的安装 随着科技的发展,我们的生活变得越来越便捷,而社区查询软件的出现更是为我们的生活带来了前所未有的舒适感。 科鑫互动科技有限公司开发的社区查询软件是一款专为社区居民量身定制的应用程序,旨在为他们提供全方位、多层次的生活服务。该软件简单易用的界面和丰富的功能受到了广大用户的https://www.smart-display.cn/gnaFV.html
9.软件工程网络15个人作业3——案例分析杰micc表面需求即为学校相关事物的查询和处理,潜在需求为希望可以在软件里寻求更多的乐趣,列如交友等等. 功能:你要设计什么样的功能? 为何要做这个功能,而不是其他功能? 为什么用户会用你的产品/功能? 你的创新在哪里? 可以用 NABCD 分析(http://www.cnblogs.com/xinz/archive/2010/12/01/1893323.html). https://www.cnblogs.com/jiemicc/p/8686402.html
10.触摸屏软件提供触摸屏查询软件和触摸屏查询系统以及触摸屏浏览器多媒体触摸屏软件, 触摸屏查询软件, 触摸屏查询系统的开发与制作,界面美观,动态管理内容,减少后期维护 1. 点击链接查看多媒体触摸查询系统案例 2. 触摸查询系统QQ在线咨询: 3. 微信咨询:13183843395(扫描下方二维码) 观看多媒体触摸查询系统演示,QQ:43361182 多媒体触摸查询系统开发制作演示,提供多媒体触摸查询系统软http://www.51touch.com/company/software/
11.烟草查生产日期的软件叫啥零代码企业数字化知识站烟草查生产日期的软件可以叫做“烟草追溯系统”或者“烟草生产日期查询工具”等。烟草追溯系统是一个专门用于跟踪和记录烟草产品从生产到销售全过程的软件工具,通过该系统,用户可以轻松查询到每一批次烟草产品的生产日期、批次号、产地等信息。这种工具通过条形码或二维码技术进行信息采集和记录,确保信息的准确性和可靠性。https://www.jiandaoyun.com/blog/article/513290/
12.鼎深案例多点查询软件多点查询软件的优势在于;第一,软件适用触摸屏机器,由触控设备,利用手势在机器上面进行触控查询,随着科技发展越大,能够让大家感到新鲜,何况现在的智能手机,都是触摸屏系列,排除了十年前的带按键的手机,说明时代已经在改变。 触摸屏查询软件系列让触摸屏在新一代社会上,以新科技的名称发展下去。多媒体触摸查询软件的性http://www.szdstouch.com/dingshenkeji/anli/duodianchaxunruanjian/360.html
13.(八)光盘的挂载与解挂挂载CentOS镜像rpm安装软件详细学习笔记在上面的案例中已经挂载了CentOS镜像 第一步:使用cd命令,切换到挂载目录 # cd /media/CentOS7 1 第二步:使用cd命令,切换到Packages软件包中 # cd Packages 1 第三步:查询我们要安装的软件包 # ls | grep firefox firefox-60.2.2-1.el7.centos.x86_64.rpm 1 2 第四步:使用rpm -ivh命令安装软件 # https://blog.csdn.net/qq_43555873/article/details/127031270
14.信雅达:发行股份及支付现金购买资产并募集配套资金暨关联交易报告3、根据近期国内 A 股上市公司的并购案例,交易标的属于“信息传输、软件 和信息技术服务业”的可比案例市盈率平均值为 13.67、中位数为 13.34,具体可 参见本报告书“第六节 交易标的评估情况”之“四、董事会对交易标的评估合理性 以及定价的公允性分析”之“(六)交易定价的公允性分析”。上市公司后续收购对 价https://stock.stockstar.com/notice/JC2015060200003529_18.shtml
15.汽车维修查询软件大全汽车维修查询推荐下载PP助手为您提供汽车维修查询软件有哪些大全推荐,在这里我们为您提供汽车维修查询软件有哪些软件下载资源,汽车维修查询软件有哪些安卓版本、官方版本&老版本下载地址合集,还可查阅相关汽车维修查询软件有哪些攻略大全,欢迎到PP助手下载。https://wap.pp.cn/topic/499335/
16.命令,网络与磁盘命令,软件安装命令51CTO博客能够熟练使用yum进行查找、安装、卸载软件 能够熟练使用rpm进行查找、安装、卸载软件 能够熟练编写常用的shell脚本 1 Linux文件管理 1.1 touch命令 在Windows系统中,我们如果想创建一个文本文档或者word文件的时候,通常的做法是 1. 鼠标右键---新建---文本文档,这样的话,我们就成功的创建了一个文件,而在Linux中,我们https://blog.51cto.com/u_15472166/4929931
17.XDP(eXpressDataPath):在操作系统内核中实现快速可编程包5.1 案例一:软件路由(software routing) 内核数据平面 & 控制平面(BIRD/FRR) Linux 内核实现了一个功能完整的路由表,作为数据平面,支持 ?policy routing ?source-specific routing ?multipath load balancing, and more. 对于控制平面,Bird [10] 或 FRR [17] 这样的路由守护进程( routing daemons)实现了https://www.shangyexinzhi.com/article/11829633.html
18.软件设计师考试2025报名时间视频教程考试大纲成绩查询2022年下半年软件设计师真题参考答案版(上午综合知识)17844查看试题在线考试 2022年下半年软件设计师真题(下午案例分析)9504查看试题在线考试 2022年上半年软件设计师真题(上午综合知识)1029查看试题在线考试 考试资讯报名简章|报名费用|准考证|成绩查询|证书领取 https://www.cnitpm.com/rs/
19.免费法律咨询,法律知识查询,文书合同及指导案例查询等服务法律家提供法律软件、法学教学软件、法律考试软件、法律数据库的研发服务,用户可进行免费法律咨询,查询法律法规知识、指导案例审判规则、法律文书、合同范本,是大型综合法律门户网。http://www.fae.cn/