前言:本系列文章适合有初/中级.NET知识的同学阅读。
(1)本系列文章,旨在讲述研发一个中大型项目所需要了解的一系列“基本构件”,并提供这些“基本构件”的【最简单】、【最快速】使用方法!!(并不深究技术原理)
(2)通过阅读本系列文章,能让你在正规“项目研发”方面快速入门+进阶,并能达成“小团队构建大网站”的目的。
(3)本系列文章采用的技术,已成功应用到人工智能、产业互联网、社区电商、游戏、金融风控、智慧医疗、等项目上。
限时下载:
Web服务的负载均衡-示例代码(dp4-WebBalance.rar)
【要点综述1】:为了演示Web服务的负载均衡,本文会创建3个形式一致的web服务(或者说,创建1个web服务但分别拷贝部署在3个不同的地址),然后在客户端创建一个代理以“负载均衡”的算法形式远程调用这3个web服务。
【要点综述2】:为了实现“统一/透明”的调用形式连接“web服务端”与“客户端”两者,一个居中的“接口”类是必须创建的,且所有远程web服务需要继承此接口。
【要点综述3】:Web Api是一个经典的http服务提供形式,WCF也是一个经典的两端通信模式,本文还将会极巧妙的整合这两者,让一个服务一次编写同时具备Web Api与WCF两者的特性。
我们首先在Visual Studio中新建第一个名字叫“YZZ.Interface”的解决方案+类库工程,并在此工程中创建“IBase接口”与“Person实体类”,代码分别如下:
IBase接口:
using System.ServiceModel;//需要添加对System.ServiceModel.dll程序集的引用
using System.ServiceModel.Web;//需要添加对System.ServiceModel.Web.dll程序集的引用
namespace YZZ.Interface
{
[ServiceContract]
public interface IBase
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/AccessRight", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
Person AccessRight(int age);
}
}
Person实体类:
namespace YZZ.Interface
{
public class Person
{
public string name;
public int age;
public int right;
}
}
如上代码所示,IBase接口中定义了一个通过年龄来做权限判断的AccessRight方法,并在该方法上附加了OperationContract与WebInvoke两个属性。OperationContract这个属性是用来给方法赋予WCF的特性,而WebInvoke这个属性则是给方法赋予了Web Api的特性。
编译该解决方案,获得YZZ.Interface.dll。
然后,我们再在Visual Studio中新建第二个名字叫“YZZ.Service”的解决方案+WCF服务应用程序工程,并在此工程中创建名为“MyBaseService.svc”的WCF服务文件,该文件的后台代码如下:
using YZZ.Interface;//需要添加前述IBase接口定义的YZZ.Interface.dll的引用
namespace YZZ.Service
{
public class MyBaseService : IBase
{
public Person AccessRight(int age)
{
if (age > 27)
return new Person { name = "管理员", age = age, right = 1 };
else
return new Person { name = "学生/员工", age = age, right = 0 };
}
}
}
如上代码所示,MyBaseService类实现了IBase接口中定义的AccessRight方法。
并且,此时我们还需要在此工程的Web.config中做如下两项配置,才能使得WCF与Web Api的特性在AccessRight方法身上完全见效。
配置一:在
<services>
<service name="YZZ.Service.MyBaseService">
<endpoint address="webapi" binding="webHttpBinding" contract="YZZ.Interface.IBase" behaviorConfiguration="WebApiEndPointBehavior" />
<endpoint address="" binding="basicHttpBinding" contract="YZZ.Interface.IBase" />
service>
services>
配置二:在
<endpointBehaviors>
<behavior name="WebApiEndPointBehavior">
<webHttp />
behavior>
endpointBehaviors>
如此一来,AccessRight方法就兼具了Web Api与WCF的双重特性。其Web Api(Web服务)的调用路径如下:
http://部署的服务器路径(ip+port)/MyBaseService.svc/webapi/AccessRight
为了演示Web服务的负载均衡的效果,现在我们把AccessRight方法的内容稍做修改成3个版本,分别编译YZZ.Service工程后部署在3个不同的地方(如何部署请参考其它资料,这是基础知识)。如下:
部署地址1:http://139.244.52.136:120/MyBaseService.svc
对应AccessRight代码1:
public Person AccessRight(int age)
{
if (age > 27)
return new Person { name = "管理员", age = age, right = 1 };
else
return new Person { name = "学生/员工", age = age, right = 0 };
}
部署地址2:http://139.244.52.136:220/MyBaseService.svc
对应AccessRight代码2:
public Person AccessRight(int age)
{
if (age > 27)
return new Person { name = "管理员1", age = age, right = 1 };
else
return new Person { name = "学生/员工1", age = age, right = 0 };
}
部署地址3:http://139.244.52.136:230/MyBaseService.svc
对应AccessRight代码3:
public Person AccessRight(int age)
{
if (age > 27)
return new Person { name = "管理员2", age = age, right = 1 };
else
return new Person { name = "学生/员工2", age = age, right = 0 };
}
当“接口”与其对应的“3个Web服务”全部准备就绪,我们最后就来创建一个客户端以“负载均衡”的算法形式远程调用这3个web服务。
我们再次打开Visual Studio,新建第三个名字叫“YZZ.Client”的解决方案+控制台工程。然后,我们做如下四步操作:
【第一步】:从NuGet添加引用DeveloperSharp包。并添加YZZ.Interface.dll的引用。
【第二步】:创建一个名为DeveloperSharp.xml的配置文件,并在该文件中设置如上3个web服务的负载均衡策略。文件内容如下:
<DeveloperSharp>
<IServiceList>
<IService Id="YZZ.Interface.IBase">
<Service Id="A11" Enable="true" Weight="100" BindType="basicHttpBinding" Address="http://139.244.52.136:120/MyBaseService.svc"/>
<Service Id="A22" Enable="true" Weight="100" BindType="basicHttpBinding" Address="http://139.244.52.136:220/MyBaseService.svc"/>
<Service Id="A33" Enable="true" Weight="100" BindType="basicHttpBinding" Address="http://139.244.52.136:230/MyBaseService.svc"/>
IService>
IServiceList>
DeveloperSharp>
对此xml配置文件说明如下:
(1) 每一个IService节点代表了一组Web服务,此节点的Id值(本文示例值是:YZZ.Interface.IBase)必须是这组Web服务的“基类接口”的完全限定名。
(2) Service节点中的Weight属性代表了使用权重。本文示例的3个服务的Weight值分别是100、100、100,则这3个服务的负载均衡使用分配比例将会是1:1:1。若把这三个值分别设置为100、50、50,则这3个服务的使用分配比例将会变为2:1:1。设置成你想要的比例吧。
(3) Service节点中的Enable属性代表了是否可用。true代表可用,false代表不可用。
【第三步】:在工程配置文件App.config(或Web.config)中添加appSettings节点,节点内容如下:
<appSettings>
<add key="DatabaseType" value="" />
<add key="ConnectionString" value="" />
<add key="ErrorPage" value="" />
<add key="ErrorLog" value="D:\Test2\YZZ.Client\log.txt" />
<add key="ConfigFile" value="D:\Test2\YZZ.Client\DeveloperSharp.xml" />
appSettings>
其中,ConfigFile的设置是为了链接前述的DeveloperSharp.xml这个配置文件。ErrorLog则是设置一个错误日志文件。它们均需要设置为文件的“绝对路径”(此处使用“绝对路径”而不是“相对路径”,一是有利于安全性,二是有利于分布式部署)
【第四步】:在控制台应用类的代码中,添加创建“Web服务”负载均衡调用的工具IUtility.GetService(),并通过该工具调用远程的Web服务,注意:核心代码就一行而已!!此示例连续3次调用Web服务,看会显示什么结果。如下:
class Program
{
static void Main(string[] args)
{
YZZ.Interface.Person p;
DeveloperSharp.Framework.CoreUtility.IUtility IU = new DeveloperSharp.Framework.CoreUtility.Utility();//创建“Web服务”负载均衡调用的工具
//第一次调用远程Web服务
p = IU.GetService<YZZ.Interface.IBase>().AccessRight(20);
Console.WriteLine(p.name);
//第二次调用远程Web服务
p = IU.GetService<YZZ.Interface.IBase>().AccessRight(20);
Console.WriteLine(p.name);
//第三次调用远程Web服务
p = IU.GetService<YZZ.Interface.IBase>().AccessRight(20);
Console.WriteLine(p.name);
Console.ReadLine();
}
}
从以上示例代码我们可以清晰的得知:IUtility.GetService()就是实现负载均衡的关键所在。泛型T需要设置为被调用“Web服务组”的“基类接口”,而IUtility.GetService()方法则会每次根据配置的负载均衡策略创建对应的远程Web服务代理。
YZZ.Client控制台工程输出显示结果如下:
学生/员工
学生/员工1
学生/员工2
最后提示一点:若要把一组Web服务的负载均衡应用改为单Web服务应用,只需要把DeveloperSharp.xml配置文件中IService节点下的Service节点数量设置为一个即可实现。
后记:读完本文,你有没有发现,“微服务”中常用的注册、发现、服务降级、等功能,往往可通过修改DeveloperSharp.xml这个配置文件来实现?未完待续…
本文技术点思路梳理:
【附注】:下载示例均已成功运行通过。但有些辅助设置需要自己调整。技术支持+获取更多宝贵资源:请微信扫描文末二维码,备注“进群”!
如果文章对你有帮助,请点赞、收藏、关注(原创内容,欢迎转载,转载请注明出处)
出处:https://developersharp.blog.csdn.net/
【技术支持+获取更多宝贵资源,点击下方名片,备注“进群”】