首页 文章 精选 留言 我的

精选列表

搜索[asp],共1555篇文章
优秀的个人博客,低调大师

ASP.NET Core微服务之基于Consul实现服务治理(3)

一、示例整体架构 此示例会由一个API Gateway, 一个Consul Client以及三个Consul Server组成,有关Consul的Client和Server这两种模式的Agent的背景知识,请移步我之前的文章加以了解:《.NET Core微服务之基于Consul实现服务治理》。其中,Consul的Client和Server节点共同构成一个Data Center,而API Gateway则从Consul中获取到服务的IP和端口号,并返回给服务消费者。这里的API Gateway是基于Ocelot来实现的,它不是这里的重点,也就不过多说明了,不了解的朋友请移步我的另一篇:《.NET Core微服务之基于Ocelot实现API网关服务》。 二、Consul集群搭建 2.1 Consul镜像拉取 docker pull consul:1.4.4 验证:docker images 2.2 Consul Server实例创建 以下我的实践是在一台机器上(CentOS 7)操作的,因此将三个实例分别使用了不同的端口号(区别于默认端口号8500)。实际环境中,建议多台机器部署。 (1)Consul实例1 docker run -d -p 8510:8500 --restart=always -v /XiLife/consul/data/server1:/consul/data -v /XiLife/consul/conf/server1:/consul/config -e CONSUL_BIND_INTERFACE='eth0' --privileged=true --name=consul_server_1 consul:1.4.4 agent -server -bootstrap-expect=3 -ui -node=consul_server_1 -client='0.0.0.0' -data-dir /consul/data -config-dir /consul/config -datacenter=xdp_dc; (2)Consul实例2 为了让Consul实例2加入集群,首先获取一下Consul实例1的IP地址: JOIN_IP="$(docker inspect -f '{{.NetworkSettings.IPAddress}}' consul_server_1)"; docker run -d -p 8520:8500 --restart=always -v /XiLife/consul/data/server2:/consul/data -v /XiLife/consul/conf/server2:/consul/config -e CONSUL_BIND_INTERFACE='eth0' --privileged=true --name=consul_server_2 consul:1.4.4 agent -server -ui -node=consul_server_2 -client='0.0.0.0' -datacenter=xdp_dc -data-dir /consul/data -config-dir /consul/config -join=$JOIN_IP; (3)Consul实例3 docker run -d -p 8530:8500 --restart=always -v /XiLife/consul/data/server3:/consul/data -v /XiLife/consul/conf/server3:/consul/config -e CONSUL_BIND_INTERFACE='eth0' --privileged=true --name=consul_server_3 consul:1.4.4 agent -server -ui -node=consul_server_3 -client='0.0.0.0' -datacenter=xdp_dc -data-dir /consul/data -config-dir /consul/config -join=$JOIN_IP; 验证1:docker exec consul_server_1 consul operator raft list-peers 验证2:http://192.168.16.170:8500/ 2.3 Consul Client实例创建 (1)准备services.json配置文件,向Consul注册两个同样的Product API服务 { "services": [ { "id": "core.product-/192.168.16.170:8000", "name": "core.product", "tags": [ "xdp-/core.product" ], "address": "192.168.16.170", "port": 8000, "checks": [ { "name": "core.product.check", "http": "http://192.168.16.170:8000/api/health", "interval": "10s", "timeout": "5s" } ] }, { "id": "core.product-/192.168.16.170:8001", "name": "core.product", "tags": [ "xdp-/core.product" ], "address": "192.168.16.170", "port": 8001, "checks": [ { "name": "core.product.check", "http": "http://192.168.16.170:8001/api/health", "interval": "10s", "timeout": "5s" } ] } ] } 有关配置文件的细节,请移步另一篇文章:《.NET Core微服务之基于Consul实现服务治理(续)》 (2)Consul Client实例 docker run -d -p 8550:8500 --restart=always -v /XiLife/consul/conf/client1:/consul/config -e CONSUL_BIND_INTERFACE='eth0' --name=consul_client_1 consul:1.4.4 agent -node=consul_client_1 -join=$JOIN_IP -client='0.0.0.0' -datacenter=xdp_dc -config-dir /consul/config (3)验证 2.4 服务检查监控邮件提箱 (1)为Client添加watches.json { "watches": [ { "type": "checks", "handler_type": "http", "state": "critical", "http_handler_config": { "path": "http://192.168.16.170:6030/api/Notifications/consul", "method": "POST", "timeout": "10s", "header": { "Authorization": [ "token" ] } } } ] } *.这里的api接口http://192.168.16.170:6030/api/Notifications/consul是我的一个通知服务接口,下面是实现的代码 /// <summary> /// 发送Consul服务中心健康检查Email /// </summary> [HttpPost("consul")] public async Task SendConsulHealthCheckEmail() { using (var stream = new MemoryStream()) { HttpContext.Request.Body.CopyTo(stream); var ary = stream.ToArray(); var str = Encoding.UTF8.GetString(ary); dynamic notifications = JsonConvert.DeserializeObject(str); if (notifications == null || notifications.Count == 0) { return; } var title = "XDP服务中心健康检查通知"; var emailBody = new StringBuilder($"<span style='font-weight:bold; color:red;'>{title}</span> : <br/>"); foreach (var notification in notifications) { emailBody.AppendLine($"---------------------------------------------------------<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>节点</span>:{notification.Node}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>服务ID</span>:{notification.ServiceID}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>服务名称</span>:{notification.ServiceName}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>检查ID</span>:{notification.CheckID}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>检查名称</span>:{notification.Name}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>检查状态</span>:{notification.Status}<br/>"); emailBody.AppendLine($"<span style='font-weight:bold;'>检查输出</span>:{notification.Output}<br/>"); emailBody.AppendLine($"---------------------------------------------------------<br/>"); } var email = new Email() { Username = _configuration["EmailSettings:Username"], Password = _configuration["EmailSettings:Password"], SmtpServerAddress = _configuration["EmailSettings:SmtpServerAddress"], SmtpPort = Convert.ToInt32(_configuration["EmailSettings:SmtpPort"]), Subject = title, Body = emailBody.ToString(), Recipients = _configuration["EmailSettings:Recipients"] }; email.Send(); } } /// <summary> /// 使用同步发送邮件 /// </summary> public void Send() { using (SmtpClient smtpClient = GetSmtpClient) { using (MailMessage mailMessage = GetClient) { if (smtpClient == null || mailMessage == null) return; Subject = Subject; Body = Body; //EnableSsl = false; smtpClient.Send(mailMessage); //异步发送邮件,如果回调方法中参数不为"true"则表示发送失败 } } } (2)验证 三、Ocelot网关配置 3.1 为Ocelot增加Consul支持 (1)增加Nuget包:Ocelot.Provider.Consul Nuget>>Install-PackageOcelot.Provider.Consul (2)修改StartUp.cs,增加Consul支持 s.AddOcelot() .AddConsul(); 更多内容,请移步:Ocelot官方文档-服务发现 3.2 修改Ocelot配置文件增加Consul配置 "GlobalConfiguration": { "BaseUrl": "http://api.xique.com", "ServiceDiscoveryProvider": { "Host": "192.168.16.170", "Port": 8550, "Type": "Consul" } } *.这里指向的是Consul Client实例的地址 此外,Ocelot默认策略是每次请求都去Consul中获取服务地址列表,如果想要提高性能,也可以使用PollConsul的策略,即Ocelot自己维护一份列表,然后定期从Consul中获取刷新,就不再是每次请求都去Consul中拿一趟了。例如下面的配置,它告诉Ocelot每2秒钟去Consul中拿一次。 "Type": "PollConsul", "PollingInterval": 2000 3.3 Service配置 // -- Service { "UseServiceDiscovery": true, "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "core.product", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/product/{url}", "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ] } 这里配置了在Consul中配置的服务名(ServiceName),以及告诉Ocelot我们使用轮询策略(RoundRobin)做负载均衡。 3.4 验证 第一次访问: 第二次访问: 四、HA示例整体架构 对于实际应用中,我们往往会考虑单点问题,因此会借助一些负载均衡技术来做高可用的架构,这里给出一个建议的HA示例的整体架构: 对于一个API请求,首先会经历一个Load Balancer才会到达API Gateway,这个Load Balancer可以是基于硬件的F5,也可以是基于软件的Nginx或LVS再搭配Keepalived,一般来说大部分团队都会选择Nginx。然后API Gateway通过部署多个,来解决单点问题,也达到负载均衡的效果。而对于API Gateway和Consul Client之间的连接,我们往往也会增加一个Load Balancer来实现服务发现的高可用,这个Load Balancer也一般会基于Nginx/LVS搭配Keepalived,API Gateway只需要访问一个Virtual IP即可。而在Consul Data Center中,Consul Server会选择3或5个,Consul Client也会部署多个,刚刚提到的Virtual IP则会指向多个Consul Client,从而防止了Consul Client的单点问题。

优秀的个人博客,低调大师

ASP.NET2.0 XML系列(6): 使用XmlReaderSettings配置XmlReader的输出

XmlReaderSettings是用来验证XML数据的一个重要的类,后面我们将用这个类来验证XML文件,这里我们先演示使用XmlReaderSettings来配置XmlReader的输出 XmlReaderSettings类的属性 名称 说明 CheckCharacters 获取或设置一个值,该值指示是否进行字符检查。 CloseInput 获取或设置一个值,该值指示当读取器关闭时,是否应关闭基础流或TextReader。 ConformanceLevel 获取或设置XmlReader将遵循的一致性级别。 IgnoreComments 获取或设置一个值,该值指示是否忽略注释。 IgnoreProcessingInstructions 获取或设置一个值,该值指示是否忽略处理指令。 IgnoreWhitespace 获取或设置一个值,该值指示是否忽略无关紧要的空白。 LineNumberOffset 获取或设置XmlReader对象的行号偏移量。 LinePositionOffset 获取或设置XmlReader对象的行位置偏移量。 NameTable 获取或设置用于原子化字符串比较的XmlNameTable。 ProhibitDtd 获取或设置一个值,该值指示是否禁用文档类型定义 (DTD) 处理。 Schemas 获取或设置在执行架构验证时使用的XmlSchemaSet。 ValidationFlags 获取或设置一个指示架构验证设置的值。此设置应用于验证架构的XmlReader对象(ValidationType属性设置为ValidationType.Schema)。 ValidationType 获取或设置一个值,该值指示XmlReader在读取时是否执行验证或类型分配。 XmlResolver 设置用来访问外部文档的XmlResolver。 实例: protected void Page_Load( object sender,EventArgse) {stringxmlFilePath=Request.PhysicalApplicationPath+@"\Employees.xml";XmlReaderSettingssettings=newXmlReaderSettings();settings.IgnoreComments=true;settings.IgnoreComments=true;try{using(XmlReaderreader=XmlReader.Create(xmlFilePath,settings)){stringresult;while(reader.Read()){if(reader.NodeType==XmlNodeType.Element){result="";for(intcount=0;count<reader.Depth;count++){result+="---";}result+="->"+reader.Name+"<br/>";this.mEmployeesLabel.Text+=result;}}}}catch(Exceptionex){this.mEmployeesLabel.Text="AnExceptionoccured:"+ex.Message;}} ->employees ---->employee ------->name ---------->firstName ---------->lastName ------->city ------->state ------->zipCode ---->employee ------->name ---------->firstName ---------->lastName ------->city ------->state ------->zipCode 本文转自敏捷的水博客园博客,原文链接 http://www.cnblogs.com/cnblogsfans/archive/2008/03/16/1108481.html如需转载请自行联系原作者 王德水

优秀的个人博客,低调大师

ASP.NET中使用三层架构事务的技巧实战

在我知道的.NET中,执行事务有两种方法,一种是自动事物,使用起来相当简单,但是需要配置服务器,如果你用的是web共享主机,即没有权限配置自己的服务器,那就没必要用这种了,接下来我讲下.net中最普通的事务SqlTransaction。 接触3层也有一段时间了,了解水平一般,前段时间在想在三层中怎么使用事务呢,放在哪呢?Sqlherper ? DAL? BLL?。然后我就疯狂的百度,一直未能如愿(因为做的都是小项目,不用事务也关系不大),今天我再次查时,好好的看了csdn上的以讨论,http://topic.csdn.net/u/20091101/19/f21697d7-8f0c-4eb3-8e59-d0fe2f0b04b0.html,结合前辈和高手们的意见,自己改了一个出来。我的想法是将事务逻辑写在业务逻辑层,数据库的处理还都是在SQLHELPER,BLL层通过事务SqlTransaction传值访问DAL,再访问Sqlhelper。接下来是分块的代码。 Sqlhelper: 1 public static SqlTransaction BeginTransaction() 2 { 3 SqlConnection myConnection = new SqlConnection(DbConfig.ConnectionString); 4 myConnection.Open(); 5 SqlTransaction tran = myConnection.BeginTransaction(); 6 return tran; 7 } 8 9 public int ExecutenQuery(string cmdtxt, SqlParameter[] paras, CommandType cmdtype, SqlTransaction tran) 10 { 11 int res; 12 try 13 { 14 Cmd = new SqlCommand(cmdtxt, tran.Connection); 15 Cmd.Transaction = tran; 16 Cmd.CommandType = cmdtype; 17 Cmd.Parameters.AddRange(paras); 18 res = Cmd.ExecuteNonQuery(); 19 } 20 catch (Exception ex) 21 { 22 FileHelper.WriteMyLog(ex); 23 throw ex; 24 } 25 return res; 26 } DAL: 1 public bool test(int i,SqlTransaction tran) 2 { 3 string sql = "insert into [test]([item]) values(@i)"; 4 SqlParameter[] paras=new SqlParameter[]{new SqlParameter("@i",i)}; 5 return sqlhelper.ExecutenQuery(sql, paras, CommandType.Text, tran)>0; 6 } BLL: 1 UserDAO userdao = new UserDAO(); 2 public bool test() 3 { 4 using (SqlTransaction tran = SQLHelper.BeginTransaction()) 5 { 6 try 7 { 8 userdao.test(2, tran); 9 userdao.test(256, tran); 10 tran.Commit(); return true; 11 } 12 catch 13 { 14 tran.Rollback(); 15 return false; 16 } 17 finally 18 { 19 tran.Connection.Close();//关闭数据库连接 20 } 21 } 22 } 上述代码在此次测试中通过,若要用于真实项目中,请修改后再使用,还有本人水平一般,写的不到之处请大家见谅。欢迎大家指导指正。 本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/771636,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册