本文目的

前段时间学习WCF已经渐入佳境,完成了既定学习目标,转入分布式系统学习。本文技术路线是:

                                                   

采用wcf实现分布式服务端和客户端,客户端部署于本地主机,nginx和WCF部署于虚拟机端(分别是三个虚拟机)

此文验证:当其中一个服务端断线后,另一个服务端可以继续支撑整个会话的完成。

技术关键词

wcf,nginx,虚拟机

 (如果wcf基础知识还不是很熟,建议先学习wcf技术知识。虚拟机采用vmware,虚拟机建立的系统是Win7.

    提前准备好虚拟机,并建立三个虚拟机,每个虚拟机建立Win7系统,每个Win7系统安装.NET4.6平台。

   下载nginx程序包。)

准备工作:虚拟机与主机建立局域网

为了保障本文的测试成功,主机与三个虚拟机之间组成局域网。三个虚拟机完成下图设置



三个虚拟机完成虚拟网路设置:



选择VMnet8(因为此项外部连接是NAT模式),然后点击NAT设置。



设置NAT网关设置



三个虚拟机还需要关闭防火墙和修改入站规则



我们来从自己本地主机ping虚拟机进行验证。



我们从虚拟机向本地主机ping



以上就实现了每个虚拟机与主机的局域网建立。

wcf契约与Service

本文的wcf服务代码没有很特殊的地方,贴代码
1 namespace NginxWCFTest_Contract 2 { 3 [ServiceContract] 4 public
interface IOutputSomething 5 { 6 [OperationContract] 7 string
GetContentData(int i); 8 [OperationContract] 9 string GetIpAddress(); 10 }
11 } View Code 1 namespace NginxWCFTest_Service 2 { 3 public class
OutputSomethingService:IOutputSomething 4 { 5 string threadName; 6 readonly
object lockObject = new object(); 7 8 public string GetContentData(int i) 9
{10 lock (lockObject) 11 { 12 threadName = i.ToString(0 + "-" + "我是主机:" +
GetIpAddress());13 } 14 return string.Format("序列号:{0},线程号:{1}", i, threadName);
15 } 16 public string GetIpAddress() 17 { 18 string AddressIP = string.Empty;
19 foreach (IPAddress _IPAddress in
Dns.GetHostEntry(Dns.GetHostName()).AddressList)20 { 21 if
(_IPAddress.AddressFamily.ToString() =="InterNetwork") 22 { 23 AddressIP =
_IPAddress.ToString();24 } 25 } 26 return AddressIP; 27 } 28 } 29 } View
Code
wcf服务端宿主(部署于192.168.21.129和192.168.21.130)
1 namespace NginxWCFTest_Hosting 2 { 3 class Program 4 { 5 static void
Main(string[] args) 6 { 7 ServiceHost host = new ServiceHost(typeof
(OutputSomethingService)); 8 host.Open(); 9 //host.Opened += delegate 10 //{
11 // Console.WriteLine(host.Description.Endpoints[0].Address.Uri +
"已经启动,按任意键终止服务!");12 //}; 13 Console.Read(); 14 } 15 } 16 } View Code
 如果wcf基础知识扎实的话, 宿主的代码很easy,我们重点需要关注的是配置信息
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="
metaBehavior"> <!-- 为避免泄漏元数据信息, 请在部署前将以下值设置为 false --> <serviceMetadata
httpGetEnabled="True" httpsGetEnabled="True" httpGetUrl="
http://192.168.21.129:80/OutputSomethingService/meta"/> <!-- 要接收故障异常详细信息以进行调试,
请将以下值设置为true。在部署前设置为 false 以避免泄漏异常信息 --> <serviceDebug
includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors>
</behaviors> <services> <service name="
NginxWCFTest_Service.OutputSomethingService" behaviorConfiguration="metaBehavior
"> <!--修改Binding为webHttpBinding--> <endpoint address="" binding="
basicHttpBinding" contract="NginxWCFTest_Contract.IOutputSomething" >
<identity> </identity> </endpoint> <endpoint address="mex" binding="
mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add
baseAddress="http://192.168.21.129:80/OutputSomethingService/" />
</baseAddresses> </host> </service> </services> </system.serviceModel> View Code

可以看得到服务端宿主的url端口是80,因为80是系统自带的默认端口。一般80作为网页服务器的访问端口,比如一个网站的ip地址是123.123.123.123,我们访问的是123.123.123.123:80
 只是80是默认端口可以省略。



 

后面针对为什么用80端口会再一次介绍。

wcf客户端宿主(部署于192.168.21.3)

客户端宿主代码跟普通没有区别,唯一需要注意的是配置代码
namespace NginxWCFTest_Client { class Program { static void Main(string[]
args) {string AddressIP = string.Empty; foreach (IPAddress _IPAddress in
Dns.GetHostEntry(Dns.GetHostName()).AddressList) {if
(_IPAddress.AddressFamily.ToString() =="InterNetwork") { AddressIP =
_IPAddress.ToString(); } } Console.WriteLine("本机IP是:" + AddressIP); using
(ChannelFactory<IOutputSomething> channelFactory =new
ChannelFactory<IOutputSomething>("OutputSomethingService")) { //
ChannelFactory:一个创建不同类型通道的工厂,客户端使用这些通道将消息发送到不同配置的服务终结点//创建通道 IOutputSomething
proxy = channelFactory.CreateChannel(); for (int i = 0; i < 20; i++) {
Console.WriteLine(proxy.GetContentData(i)); } Console.Read(); } } } View Code


大家可以看到客户端指向的地址是jackchen.com地址。这个地址是nginx虚拟机的域名。为此,我们需要做以下事情。

主机域名处理

nginx虚拟机主机域名处理:



主机域名的文件路径地址在“C:\Windows\System32\drivers\etc\hosts"
上图红箭头为新增加域名,如果IE浏览器中输入jackchen.com即相当于输入http://192.168.21.128

WCF服务端主机域名处理



192.168.21.130与上图类似,配置为192.168.21.130  jackchen.com。

wcf客户端域名配置如下

          

nginx应用

上面讲了WCF分布式服务的客户端和服务端,也讲了主机域名的处理。现在讲讲Nginx的作用和为什么要做域名处理

nginx的基础知识我就多讲了,此处链接http://tengine.taobao.org/book/chapter_09.html
<http://tengine.taobao.org/book/chapter_09.html>.

从上一步的主机域名解析就可以知道,WCF客户端指向的是ngnix的虚拟机(192.168.21.128),然后由nginx做均衡负载和备份机制管理,

                        未使用nginx



使用nginx



nginx部署于192.168.21.128,需要对nginx文件夹中config文件进行配置。



配置信息为:
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/
error.log notice; #error_log logs/error.log info; pid logs/nginx.pid; events {
worker_connections1024; } http { include mime.types; default_type application
/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local]
"$request"' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent"
"$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on;
#tcp_nopush on; #keepalive_timeout0; keepalive_timeout 65; #gzip on; server {
listen80; server_name jackchen.com; #charset koi8-r; #access_log logs/
host.access.log main; location/ { autoindex off;#是否打开目录浏览 root
\html\Views\Home;#默认主页目录在nginx安装目录的html子目录。 index Index.cshtml index.html
index.htm;#起始页 proxy_pass http://jackchen.com; } #error_page 404 /404.html; #
redirect server error pages to thestatic page /50x.html # error_page 500 502 503
504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to
Apache listening on127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://
127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:
9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; #
fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME/
scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to
.htaccess files,if Apache's document root # concurs with nginx's one #
#location~ /\.ht { # deny all; #} } upstream linuxidc { server 127.0.0.1:8001;
server127.0.0.1:8002; server 127.0.0.1:8003; } upstream jackchen.com { server
192.168.21.129:80; server 192.168.21.130:80; } # another virtual host using mix
of IP-, name-, and port-based configuration # #server { # listen 8000; # listen
somename:8080; # server_name somename alias another.alias; # location / { #
root html; # index index.html index.htm; # } #} # HTTPS server # #server { #
listen443 ssl; # server_name localhost; # ssl_certificate cert.pem; #
ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; #
ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; #
ssl_prefer_server_ciphers on; # location/ { # root html; # index index.html
index.htm; # } #} } View Code
      其中的修改点为:

              

upstream是配置集群,集群由192.168.21.129   和192.168.21.130组成

修改完了之后准备开启nginx,下图是进入nginx.exe所在的文件夹



                接着输入 start nginx可以启动nginx,输入nginx -s stop可以停止nginx,输入nginx -s
reload可以重启nginx 

效果展示

启动两个服务端和nginx,同时启动客户端,效果图如下



关闭192.168.21.130效果图如下

        

 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信