很多情况下基于wcf的复杂均衡都首选zookeeper,这样可以拥有更好的控制粒度,但zk对 C# 不大友好,实现起来相对来说比较麻烦,实际情况下,如果你的负载机制粒度很粗糙的话,用nginx就可以搞定啦,既可以实现复杂均衡,又可以实现双机热备,以最小的代码量实现我们的业务。
一:准备的材料
1. 话不多说,一图胜千言,图中的服务器都是采用vmware虚拟化,如下图:
- 三台windows机器 ,两个WCF的windows服务器承载(192.168.23.187,192.168.23.188),一台Client的服务器(192.168.23.1)
- 一台Centos机器,用来承载web复杂均衡nginx(192.168.23.190)。
- 在所有的Client的Hosts文件中增加host映射:【192.168.23.190 cluster.com】,方便通过域名的形式访问nginx所在服务器的ip地址。
二:环境搭建
1. WCF程序
既然是测试,肯定就是简单的程序,代码就不完全给出了。
- HomeService实现类代码如下(输出当前server的ip地址,方便查看):
publicclassHomeService:IHomeService
{
publicstringDoWork(stringmsg)
{
varip=Dns.GetHostAddresses(Dns.GetHostName()).FirstOrDefault(i=>i.AddressFamily==
AddressFamily.InterNetwork).ToString();
returnstring.Format("当前request由server={0}返回",ip);
}
}
- App.Config代码
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntimeversion="v4.0"sku=".NETFramework,Version=v4.5.2"/>
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behaviorname="">
<serviceMetadatahttpGetEnabled="true"httpsGetEnabled="true"/>
<serviceDebugincludeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<servicename="WcfService.HomeService">
<endpointaddress="/HomeService"binding="basicHttpBinding"contract="WcfService.IHomeService">
<identity>
<dnsvalue="localhost"/>
</identity>
</endpoint>
<endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
<host>
<baseAddresses>
<addbaseAddress="http://192.168.23.187:8733"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
因为windows的两台机器的ip地址是192.168.23.187,192.168.23.188,所以部署的时候注意一下config中的baseAddress地址。
2. centos上的nginx搭建
nginx我想大家用的还是比较多的,去官网下载最新的就好【nginx-1.13.6】:http://nginx.org/en/download.html,下载之后,就是常规的三板斧安装!!!
[root@localhostnginx-1.13.6]#yuminstall-ygccgcc-c++automakepcrepcre-develzlibzlib-developensslopenssl-devel
[root@localhostnginx-1.13.6]#./configure–prefix=/usr/myapp/nginx
[root@localhostnginx-1.13.6]#make&&makeinstall
然后在nginx的安装目录下面找到conf文件,修改里面的nginx.conf 配置。
[root@localhostnginx]#cdconf
[root@localhostconf]#ls
fastcgi.confkoi-utfnginx.confuwsgi_params
fastcgi.conf.defaultkoi-winnginx.conf.defaultuwsgi_params.default
fastcgi_paramsmime.typesscgi_paramswin-utf
fastcgi_params.defaultmime.types.defaultscgi_params.default
[root@localhostconf]#vimnginx.conf
详细配置如下,注意下面“标红”的地方,权重按照1:5的方式进行调用,关于其他的配置,大家可以在网上搜一下就可以了。
#usernobody;
worker_processes1;
#error_loglogs/error.log;
#error_loglogs/error.lognotice;
#error_loglogs/error.loginfo;
#pidlogs/nginx.pid;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
#log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'
#'$status$body_bytes_sent"$http_referer"'
#'"$http_user_agent""$http_x_forwarded_for"';
#access_loglogs/access.logmain;
sendfileon;
#tcp_nopushon;
#keepalive_timeout0;
keepalive_timeout65;
#gzipon;
upstreamcluster.com{
server192.168.23.187:8733weight=1;
server192.168.23.188:8733weight=5;
}
server{
listen80;
server_namelocalhost;
#charsetkoi8-r;
#access_loglogs/host.access.logmain;
location/{
roothtml;
indexindex.htmlindex.htm;
proxy_passhttp://cluster.com;
#设置主机头和客户端真实地址,以便服务器获取客户端真实IP
proxy_set_headerX-Forwarded-Host$host;
proxy_set_headerX-Forwarded-Server$host;
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
proxy_set_headerX-Real-IP$remote_addr;
}
#error_page404/404.html;
#redirectservererrorpagestothestaticpage/50x.html
#
error_page500502503504/50x.html;
location=/50x.html{
roothtml;
}
#proxythePHPscriptstoApachelisteningon127.0.0.1:80
#
#location~\\.php${
#proxy_passhttp://127.0.0.1;
#}
#passthePHPscriptstoFastCGIserverlisteningon127.0.0.1:9000
#
#location~\\.php${
#roothtml;
#fastcgi_pass127.0.0.1:9000;
#fastcgi_indexindex.php;
#fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name;
#includefastcgi_params;
#}
#denyaccessto.htaccessfiles,ifApache'sdocumentroot
#concurswithnginx'sone
#
#location~/\\.ht{
#denyall;
#}
}
#anothervirtualhostusingmixofIP-,name-,andport-basedconfiguration
#
#server{
#listen8000;
#listensomename:8080;
#server_namesomenamealiasanother.alias;
#location/{
#roothtml;
#indexindex.htmlindex.htm;
#}
#}
#HTTPSserver
#
#server{
#listen443ssl;
#server_namelocalhost;
#ssl_certificatecert.pem;
#ssl_certificate_keycert.key;
#ssl_session_cacheshared:SSL:1m;
#ssl_session_timeout5m;
#ssl_ciphersHIGH:!aNULL:!MD5;
#ssl_prefer_server_cipherson;
#location/{
#roothtml;
#indexindex.htmlindex.htm;
#}
#}
}
3. client端的程序搭建
- 第一件事就是将 192.168.23.190 映射到本机的host中去,因为服务不提供给第三方使用,所以加host还是很轻松的。
- 然后就是client端程序添加服务引用,因为添加了host映射,所以服务引用地址就是"http://cluster.com"。代码如下:
classProgram
{
staticvoidMain(string[]args)
{
for(inti=0;i<1000;i++)
{
HomeServiceClientclient=newHomeServiceClient();
varinfo=client.DoWork("helloworld!");
Console.WriteLine(info);
System.Threading.Thread.Sleep(1000);
}
Console.Read();
}
}
最后来执行以下程序,看看1000次循环中,是不是按照权重1:5 的方式对后端的wcf进行调用的???
看到没有,是不是很????,我只需要通过cluster.com进行服务访问,nginx会自动给我负载均衡,这就是我们开发中非常简单化的wcf复杂均衡,希望本篇对你有帮助~~~~
本文转载自微信公众号「一线码农聊技术」,可以通过以下二维码关注。转载本文请联系一线码农聊技术公众号。