系统和系统之间,少不了数据的互联互通。随着微服务的流行,一个系统内的不同应用进行互联互通也是常态。
PowerDotNet的服务治理平台发源于早期的个人项目Power.Apix。这个项目借鉴了工作过的公司的服务治理方案,站在巨人的肩膀上,一步一步从无到有模仿设计和实现。
一开始,Power.Apix被设计用于基于XML的Web服务通信,因为Web服务在当时是主流通信方式,朴素版本大概长下面这个样子:
服务端:

服务端只要加上ApixClazz、ApixMethod两个特性,一个Apix服务就完美实现了:

客户端:

后来,随着个人开发经验的丰富,陆陆续续添加了更多的序列化协议的支持,而初期设计的仅支持Web服务通信则被改的面目全非。
Power.Apix支持常见的HTTP方法:

Power.Apix支持不同的序列化方式:

通过抓包分析,可以发现Power.Apix已经支持自定义请求头:

十年磨一剑。经过多年优化和改进,负载均衡、限流、黑白名单、日志等功能逐步迭代开发出来,在以HTTP协议为主流的文本协议框架里,Power.Apix现在已经非常完善和强大,尤其是部署非常方便,在一般请求应答业务场景下,完全可以取代.NET Remoting、WebApi、WebService和WCF。
简单介绍完Power.Apix,下面再来说说本文的主题服务治理平台。
我们常见的传统的RPC接口调用,比如WebApi、WebService、WCF、.NET Remoting、gRPC、Thrift、Hessian、自定义RPC协议(比如个人项目Power.Apix)等,如果是少量调用,还好说。但是一旦接口多起来,系统关系复杂,就容易造成各种混乱。
我已经不止看到一个系统,不论是.Net还是Java开发的应用,都要配置各种接口服务地址,调用的地方各种拼接接口名称,各种HTTP帮助类,看着就不够优雅,可以说都是demo水平。咩哈哈,就是demo水平。
PowerDotNet在借鉴主流微服务治理框架和协议(包括但不限于ZooKeeper、Consul、Nacos、HSF、ETCD、Dubbo、Spring Cloud、Ocelot、Hessian、gRPC、Thrift、Kubernates等)的基础上,独立开发出了一套简洁高效的服务治理平台。
在一个基于服务(SOA)的分布式环境中,常见的消息交互模式(Message Exchange Pattern,即MEP)主要包括如下几种:
1、RequestReply:经典请求应答模型,客户端发起一个请求后会等待一个响应才可以进行下一次请求
2、Oneway:客户端发起一个请求后不等待一个响应
3、Duplex:双向通信,客户端发起请求得到服务端一个响应,服务端再回调通知客户端一个响应,HTTP和TCP协议会有不同的实现逻辑
4、Streaming:客户端发起一个或多个请求 , 等待一个或多个响应
PowerDotNet目前完美支持RequestReply这一经典交互模式,毕竟来源于web环境下以HTTP为文本协议的Power.Apix,当然简单的Oneway模式只需要简单改造不多的框架代码就可以支持。
PowerDotNet早期自研了一套基于ZooKeeper的注册中心Power.RegistryCenter,后来逐步改造放弃ZooKeeper为默认注册中心,因为曾经某厂的ZooKeeper由于磁盘IO太高,导致ZooKeeper集群挂掉,进而导致重大生产事故。
从CAP理论上来说,ZooKeeper保证的是CP(一致性和分区容错性),然而注册中心尤其是服务发现功能更应该保证的是AP(可用性和分区容错性),可用性比数据一致性更加重要 。
PowerDotNet最新自研的注册中心遵循AP原则,高可用性基于DB、本地缓存、Redis和ETCD,且Redis和ETCD都是可插拔的插件式可选模式,用户选择更多,同时还能保证高可用。
从服务拉取方式和性能上来看,PowerDotNet的注册中心采用的是客户端(Power.RegistryCenter.Client)拉取模式,客户端定时(默认间隔30秒,这个参考了SpringCloud的Eureka)主动拉取(续租)服务端(Power.RegistryCenter.Server)服务并缓存在本地,而早期的ZooKeeper客户端监听服务列表变化,服务变更主动推送给消费者,在规模较大的服务集群上,很容易产生性能问题。
复用是PowerDotNet设计的时候优先考虑的主题。针对不同协议的RPC接口,PowerDotNet设计的时候做了各种妥协,现已经完美支持WebApi、WebService、WCF(支持常见的几种绑定协议,包括BasicHttpBinding、WSHttpBinding、NetTcpBinding等)、.NET Remoting(支持HTTP和TCP协议)、gRPC、Thrift、Hessian、IHttpHandler(ASPX、ASHX、个人项目Power.Apix)的互联互通。
PowerDotNet还有一个后续开发计划PowerDotNetCore,以支持.NetCore下的主要通信协议,目前.NetCore2.1、.NetCore3.0和.NET5下的WebApi已经完美支持,其他等我有空慢慢来开发实现,咩哈哈,都是脏活累活苦活呀。后续再考虑开发支持和Java接口互通。
仅需要遵循一点点PowerDotNet规范,接口生产者可以快速开发API接口,接口消费者利用PowerDotNet自动生成工具,快速生成接口消费代理类,就和调用本地方法一样容易。
如果你的系统里有不同的RPC接口形式需要互联互通,比如WebApi调用WCF,WebService调用WebApi......或者相同的RPC形式互调,PowerDotNet都能够让你以一种优雅愉悦的方式实现接口调用。
环境准备
1、(必须).Net Framework4.5+
2、(必须)关系型数据库MySQL或SqlServer或PostgreSQL或MariaDB四选一
3、(可选)分布式键值存储ETCD
4、(可选)分布式缓存Redis或Memcached二选一
5、(可选)消息队列RabbitMQ或MSMQ 二选一
6、(可选)ElasticSearch
支持自动注册和人工注册,自动注册类、字段等相关元数据。

通过心跳程序,定时(默认5秒间隔)发送心跳来判断应用服务器的可用状态(保活)。心跳程序健壮可靠,可以通过配置中心对心跳参数进行动态设置。
配合服务治理客户端工具,可以自动发现新接入或者心跳停止的服务器,自动实现服务发现。
如何保证心跳程序健壮可靠?PowerDotNet的心跳设计包含了两种常见模式:推模式和拉模式。
推模式指应用服务器主动发送心跳至平台注册中心,这是常规的心跳检查方式。
拉模式指平台注册中心通过定时任务主动对应用服务器发起心跳接口调用,间接触发应用服务器心跳程序自检。
通过推模式和拉模式进行心跳检查,可以最大程度减少某些应用(如寄宿在web容器上的服务,如果你熟悉IIS的话,应该知道IIS Worker Process默认会配置Idle Timeout 为20分钟,即该进程在20分钟内没有任何请求的话就会自动结束)自动“休眠”导致心跳线程不能被唤醒而造成的心跳判断错误。
当然拉模式是一种可关停的备选方案,通常推模式的心跳程序可以支持绝大多数应用服务的心跳检查。
在这篇文章中,我们可以从【应用部署管理】看到应用部署服务器的心跳情况,从而为实现基于心跳的服务发现打下基础。
服务发现的关键部分是注册中心,注册中心提供注册和查询(发现)功能。
服务发现主要有两种发现模式:客户端发现和服务端发现。
客户端发现模式要求客户端负责查询注册中心,获取服务提供者的列表信息,使用负载均衡算法选择一个合适的服务提供者,发起接口调用请求。
服务端发现模式则要求客户端每次都请求注册中心,由注册中心内部使用负载均衡算法选择一个合适的服务提供者,并将请求转发至该服务提供者。
这两种模式都有自己的优点和缺点,PowerDotNet可以通过开关动态实现两种发现模式的自由切换,就问你灵不灵活吧?

目前业界开源的有Nacos、Netflix Eureka、ETCD、Consul和Zookeeper等注册中心方案,PowerDotNet在参考了这些现有成熟方案之后,结合实践经验,选择了支持ETCD。PowerDotNet服务注册和发现,在使用ETCD的基础上进行了优化和改进,通过开关动态控制,使得ETCD只是一种可插拔的服务治理实现。
ETCD的管理在下一篇文章中单独讲讲。
支持服务白名单和服务消费特殊逻辑配置。
白名单里的接口可以直接消费。
服务消费可以对接口进行配置Token和签名校验特殊逻辑。

通过配置黑名单规则,按配置实现动态黑名单功能。

通过灰度发布规则,实现灰度发布功能。

主流的RPC框架在服务消费的时候,都有完备的客户端工具,支持服务鉴权、负载均衡、黑白名单、限流等功能。
PowerDotNet也优先实现了客户端形式的服务调用,支持主流功能。
但是,很多种场景下,都不得不考虑加入API网关,把API网关放到各种API服务的最前端,并且让API网关变成由各应用所发起的每个请求的入口。这样做可以明显的简化客户端调用服务端API。
PowerDotNet实现了一个通用简易功能的API网关,也支持服务鉴权、负载均衡、限流、黑白名单、灰度发布等功能,比客户端调用API接口功能还略丰富,并且可以继续扩展新功能。
PowerDotNet自研的负载均衡组件,包含随机、加权随机、轮询、加权轮询和客户端IP哈希五种算法,并提供了负载均衡接口,可按需动态扩展。
PowerDotNet自研的限流组件,通过配置中心动态调整开关,在注册中心通过后台管理系统动态配置,支持根据IP地址或者应用名称进行限流,并提供了接口,可按需动态扩展。
PowerDotNet负载均衡和限流组件,已经运用在网关和客户端,是通用的可扩展组件。
API网关支持对内外网开放,也可以同时部署两套,对内和对外的分开。在对外的网关上,建议对被消费的接口勾选加上验证签名和Token功能,网关会自动处理判断客户端请求是否合法。

为了更好的测试待发布的部署服务器,可以通过选择或者输入来动态切换,非常灵活

早期的远程服务调用好像一直是比较啰嗦且费力不讨好的,要么配置繁琐,要么引入很多依赖,要么IDE装啥插件,要么调用代码demo水平的写法(尤其各种HTTP工具类,烦不胜烦),总之调用别人的服务整体感觉就是乏味无趣。
PowerDotNet设计的远程服务调用,目标是“无配置,无引用,全自动”,截至目前来看,可以说出色的达到了这一目标。

咩哈哈,通过PowerDotNet调用RPC服务,只需要一个方法RemoteApiClient.Invoke<TRequest, TResponse>(methodName, request);完成调用,有点太简洁太优雅了。
只要每个独立API自动集成Swagger,通过管理后台都能自动识别查看。

也自动支持.Net Core应用:

上面这些工具对快速开发和排查问题非常有帮助。
参考:
https://github.com/alibaba/nacos
https://nacos.io/zh-cn/index.html
https://blog.csdn.net/marine2010/article/details/5401366
https://spring.io/projects/spring-cloud
https://github.com/ThreeMammals/Ocelot
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails