配置中心相信大家都有听过,zookeeper、apollo等等都是配置中心的代表,但大部分都是JAVA系为主的,笔者主要开发语言使用的是Golang当然也有类似于ETCD这样的组件,但是并不方便管理也无法可视化,在无意之间发现了阿里爸爸开源了nacos这个服务发现+配置中心组件,也经过了一段时间的时候在这里分享给大家 附上: 喵了个咪的博客:w-blog.cn Nacos官方Git地址:https://github.com/alibaba/nacos Nacos官方文档地址:https://nacos.io/zh-cn/docs/ Go语言SDK地址:https://github.com/sunmi-OS/gocore/tree/master/nacos PS:当前官方最新版本为 V1.1.3,阿里云有提供配置中心服务ACM使用方式和Nacos相同,使用阿里云的前提下免运维是个不错的选择 一、Nacos介绍 Nacos是阿里云中间件团队开源的一个项目,基于阿里云内部提供的ACM配置管理服务进行独立,截止到现在github已经有8K以上的star了,虽然成熟度还不能和携程开源的apollo相提并论,比较也是在阿里云上提供服务的组件稳定性还是值得相信的,当然要使用介绍Nacos必须要介绍介绍配置中心这样一个思想了。 配置中心是个老生常谈的话题,从有软件编程开始配置管理都是工程中重要的一步,当然对与一个单体应用只需要单个配置文件或环境变量的方式来管理配置就好了所以不再本文的讨论范围内,配置中心主要解决服务化或微服务化下的配置管理中的如下问题: 有效的密码管理,开发不碰触密码配置,运维人员和架构团队统一管理避免泄露; 多项目下的配置绝对统一性,不会出现配置写错导致的BUG 对于配置的编辑、存储、分发、变更管理、历史版本管理、变更审计有完善的能力 配置分组和灰度发布 有好处当然也有坏处,相对于使用配置文件我们还需要解决如下问题: 配置中心异常情况下服务怎么保障可用(SDK提供Cache功能当中心服务不可用会使用上一次加载的缓存配置) 配置变更后的程序生效逻辑(SDK提供配置变动订阅逻辑可以订阅配置变动编写处理逻辑) 开发过程中的配置文件调试(需要框架进行设计) 对于部分语言来说(PHP)配置中心性能的问题(Nacos的吞吐量8C16G 15K并发) 对比下来还是可以总结出配置中心利大于弊的结论 二、Nacos部署 Nacos不止支持二进制部署也支持支持Docker和K8S部署,因为Nacos是有状态服务存储的数据需要依赖于Mysql而且集群的方式需要指定slave的IP所以使用K8S并不是很好的选择(K8S使用StatefulSet来运行有状态服务),笔者这里用Docker-Composer的方式来运行Nacos
|
1 2 3 4 5 6 7 8 |
Nacos官方Docker部署方式Git地址:https://github.com/nacos-group/nacos-docker git clone https://github.com/nacos-group/nacos-docker.git 单机部署(内存模式): docker-compose -f example/standalone-derby.yaml up 单机部署(Mysql模式): docker-compose -f example/standalone-mysql.yaml up 集群部署: docker-compose -f example/cluster-hostname.yaml up |
访问:http://localhost:8848/nacos/ 就可以看到登录界面了 PS:默认用户名和密码都是 nacos 阿里云ACM服务 当然自己部署Nacos还会面临很多挑战,比如: 集群搭建 稳定性 Mysql数据库维护 配置安全保护(Nacos没有密码一说,但是ACM需要使用阿里云的密钥可以提高安全程度) PS:秉着能用服务就不自己搭建的原则笔者最终使用的是阿里云的ACM服务(当前ACM服务免费) PS:需要注意阿里云ACM和Nacos在SDK中的链接方式有不同 三、基础使用 Nacos有几个基础概念,我们只有先了解清楚之后才能更好的结合到业务场景: namespace 命名空间 Group 配置分组 DataID 具体的配置名称 一般我们使用namespace来区分不同的项目或环境,Group区分配置的差异系比如A业务获取的配置和B团队的有一些细微的差别可以通过Group来区分,最后使用DataId来区分具体的配置项 增加一个namespace 新增一个配置 支持很多种配置格式,也可以使用自定义的格式甚至直接存放代码都行 也有对应的JAVA系的示例代码 四、SDK和OpenApi使用配置 Nacos支持一下语言的SDK(当然GIT上也有很多非官方的SDK库): Java go cpp python nodejs 大家可以在官方文档中查看具体的使用方式 上面已经配置好的配置我们可以使用OpenApi来访问它
|
1 2 3 4 |
curl "http://172.16.0.13:8848/nacos/v1/cs/configs?dataId=test_config&group=DEFAULT_GROUP&tenant=b58ea912-e564-4958-b21f-3098ad15daf9" { "name":"sunmi" } |
特别注意tenant就是需要输入namespace的名称,但是不是原名是如下的名称 from:https://www.cnblogs.com/cuiyubo/p/11756777.html
View Details一、概述 consul是google开源的一个使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。 @client CLIENT表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到SERVER,本身是不持久化这些信息。 @server SERVER表示consul的server模式,表明这个consul是个server,这种模式下,功能和CLIENT都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。 @server-leader 中间那个SERVER下面有LEADER的字眼,表明这个SERVER是它们的老大,它和其它SERVER不一样的一点是,它需要负责同步注册的信息给其它的SERVER,同时也要负责各个节点的健康监测。 @raft server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是raft。 @服务发现协议 consul采用http和dns协议,etcd只支持http @服务注册 consul支持两种方式实现服务注册,一种是通过consul的服务注册http API,由服务自己调用API实现注册,另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。consul官方建议使用第二种方式。 @服务发现 consul支持两种方式实现服务发现,一种是通过http API来查询有哪些服务,另外一种是通过consul agent 自带的DNS(8600端口),域名是以NAME.service.consul的形式给出,NAME即在定义的服务配置文件中,服务的名称。DNS方式可以通过check的方式检查服务。 @服务间的通信协议 Consul使用gossip协议管理成员关系、广播消息到整个集群,他有两个gossip pool(LAN pool和WAN pool),LAN pool是同一个数据中心内部通信的,WAN pool是多个数据中心通信的,LAN pool有多个,WAN pool只有一个。 二、consul集群搭建 1)安装 首先去官网现在合适的consul包:https://www.consul.io/downloads.html 安装直接下载zip包,解压后只有一个可执行的文件consul,将consul添加到系统的环境变量里面。 #unzip consul_1.2.3_linux_amd64.zip #cp -a consul /usr/bin #consul
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Usage: consul [--version] [--help] <command> [<args>] Available commands are: agent Runs a Consul agent catalog Interact with the catalog connect Interact with Consul Connect event Fire a new event exec Executes a command on Consul nodes force-leave Forces a member of the cluster to enter the "left" state info Provides debugging information for operators. intention Interact with Connect service intentions join Tell Consul agent to join cluster keygen Generates a new encryption key keyring Manages gossip layer encryption keys kv Interact with the key-value store leave Gracefully leaves the Consul cluster and shuts down lock Execute a command holding a lock maint Controls node or service maintenance mode members Lists the members of a Consul cluster monitor Stream logs from a Consul agent operator Provides cluster-level tools for Consul operators reload Triggers the agent to reload configuration files rtt Estimates network round trip time between nodes snapshot Saves, restores and inspects snapshots of Consul server state validate Validate config files/directories version Prints the Consul version watch Watch for changes in Consul |
输入consul,出现上面的内容证明安装成功。 2)启动 consul必须启动agent才能使用,有两种启动模式server和client,还有一个官方自带的ui。server用与持久化服务信息,集群官方建议3或5个节点。client只用与于server交互。ui可以查看集群情况的。 server: cn1: #consul agent -bootstrap-expect 2 -server -data-dir /data/consul0 -node=cn1 -bind=192.168.1.202 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 cn2: #consul agent -server -data-dir /data/consul0 -node=cn2 -bind=192.168.1.201 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202 cn3: #consul agent -server -data-dir /data/consul0 -node=cn3 -bind=192.168.1.200 -config-dir /etc/consul.d -enable-script-checks=true -datacenter=dc1 -join 192.168.1.202 参数解释: -bootstrap-expect:集群期望的节点数,只有节点数量达到这个值才会选举leader。 -server: 运行在server模式 -data-dir:指定数据目录,其他的节点对于这个目录必须有读的权限 -node:指定节点的名称 -bind:为该节点绑定一个地址 -config-dir:指定配置文件,定义服务的,默认所有一.json结尾的文件都会读 […]
View Details个人观点:etcd的红火来源于kurbernetes用etcd做服务发现,而redis的兴起则来源于memcache缓存本身的局限性。 etcd是一种分布式存储,更强调的是各个节点之间的通信,同步,确保各个节点上数据和事务的一致性, 使得服务发现工作更稳定,本身单节点的写入能力并不强。 redis更像是内存型缓存,虽然也有cluster做主从同步和读写分离, 但节点间的一致性主要强调的是数据,并不在乎事务,因此读写能力很强,qps甚至可以达到10万+ 两者都是k-v存储,但redis支持更多的存储模式,包括KEY,STRING,HMAP,SET,SORTEDSET等等, 因此redis本身就可以完成一些比如排序的简单逻辑。而etcd则支持对key的版本记录和txn操作和client对key的watch,因此适合用做服务发现。 日常使用中,etcd主要还是做一些事务管理类的,基础架构服务用的比较多,容器类的服务部署是其主流。 而redis广泛地使用在缓存服务器方面,用作mysql的缓存,通常依据请求量,甚至会做成多级缓存,当然部分情况下也用做存储型redis做持续化存储。 from:https://www.cnblogs.com/nmap/p/9398346.html
View Details错误的原因,npm版本问题; 解决办法: 1》更新到最新版本:npm install npm -g 要记住全局更新 2》回退版本:npm install -g npm@5.4.0 用cnpm 会快一些 from:https://www.cnblogs.com/hou-yuan-zhen/p/11703722.html
View DetailsGradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。当前其支持的语言限于Java、Groovy、Kotlin和Scala。 到此不得不说另一个很火的工具maven,众所周知,maven的两大作用: ①:管理jar包 ②:构建项目 使用maven的缺点,XML配置文件的繁琐,特别是项目较大时,pom.xml配置眼花缭乱。 Gradle在maven的基础上,简化了配置文件,自动搜索Gradle等,使得我们创建管理项目更加简单。 一、下载,Gradle是压缩文件,下载解压即可。https://gradle.org/releases/ 这个是发布版,当然你还可以去 https://services.gradle.org/ 下载更新的版本。本人下载5.2.1的发布版 https://gradle.org/next-steps/?version=5.2.1&format=all 下载完毕后在本地目录解压即可。 二、配置环境变量:GRADLE_HOME 变量值为Gradle文件解压的实际路径,本文为例:E:\Gradle\gradle-5.2.1-all\gradle-5.2.1 在系统变量 path中加入:%GRADLE_HOME%\bin; 在cmd输入gradle -v验证是否安装成功 三、配置Gradle使用maven本地仓库,这样Gradle就不会重新下载已经存在maven本地仓库的jar包,从而节省时间和空间。 在环境变量中加入新的系统变量:GRADLE_USER_HOME 变量值是maven本地仓库的路径,本文为例C:\Users\Administrator\.m2\repository 此时,Gradle下载的文件将放到指定的仓库路径中。但是还需要修改build.gradle文件中加入mavenLocal() 引用本地仓库 repositories { //repositories闭包 mavenLocal() //配置先从本地仓库寻找jar包,优先寻找上一个配置,找到不执行下面的配置 mavenCentral() //配置从中央仓库寻找 google() //第三方仓库 jcenter() //代码托管库:设置之后可以在项目中轻松引用jcenter上的开源项目 } from:https://www.cnblogs.com/zeussbook/p/10556025.html
View DetailsServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; 调用对方提供的webservice 方法之前,加上这一句,即可解决。 ———————————————— 版权声明:本文为CSDN博主「qq_42072922」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_42072922/article/details/82620052
View Details在后台代码中进行基于https协议的请求时,我们经常会遇到一个错误:The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel(基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。) 1,先加入命名空间: using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; 2,再重载CheckValidationResult方法,返回true private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } 3.然后在执行请求的代码之前加上 ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; 通过以上三步忽略证书的错误,但是不安全,其他解决方式可以参考https://stackoverflow.com/questions/703272/could-not-establish-trust-relationship-for-ssl-tls-secure-channel-soap 然而,对于一些https接口,加了上述代码之后,调用时回报错:基础连接已经关闭: 发送时发生错误 发生该错误的原因是,使用上述代码默认是以ssl安全协议进行的,但是有些https接口服务并没有使用ssl安全协议,具体参考 https://stackoverflow.com/questions/28286086/default-securityprotocol-in-net-4-5 解决方案1:硬编码,枚举出所有的安全协议,比较简单 在ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;这行代码前面加上如下代码: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 解决方案2:让OS自动选择安全协议(推荐) https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls from:https://blog.csdn.net/ujm097/article/details/89334667
View Details前面的文章说了怎么实现代理类的生成我使用。 在使用的过程 中我又碰到了一个很棘手的问题这是我的代码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//官方查询结果xml [WebMethod ] public OrderNciis GetNciisResult(string onName, string onId) { //获取授权文件 string inLicense = LotteryMethods.GetContext(11); //生成的WSDL类() nciicGetCondition objText = new nciicGetCondition(); //获取基础URL objText.Url = LotteryMethods.GetContext(12); //编码 objText.RequestEncoding = Encoding.UTF8; //创建证书文件 X509Certificate objx509 = new X509Certificate(System.Configuration.ConfigurationSettings.AppSettings["cd"].ToString().Trim()); //证书 objText.ClientCertificates.Add(objx509); //方式可有可无 objText.UserAgent = "Client Cert Sample"; //读XML文件 string inConditions = OrderNciisXml(onName, onId); //返回查询结果XML OrderNciis model = new OrderNciis(); model.onLottery = objText.nciicCheck(inLicense, inConditions); return model; } |
代码应该是没有问题,在本地的Vs里测试没有问题,如果在ISS里使用时报基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系”证书验证失败 城刚开始我还以为是文章路径的问题,结果不是, 接着找,后来认为是IIS里配置问题,还是不对,后来,看到 网上也有很多这的问题,但是没有真正解决的,一般都 是在说怎么生成代理类,还有带有证书的过程 我想了想,还是自己想办法解决吧,我把代理类分析了一下才知道 ,原来证书是在代理类里验证的,验证后会返回一个值 表示是否通过,这就好看了, 我们定义一个方法
|
1 2 3 4 5 6 7 |
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error){ // trust any certificate!!! System.Console.WriteLine("Warning, trust any certificate"); //为了通过证书验证,总是返回true return true; } |
只要这个方法返回为True不就完了吗?呵呵 还需要几个命名空间
|
1 2 3 4 |
using System.Net; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; |
这个应该在什么时候调用呢,当然 是在构造器里合适些
|
1 2 3 4 5 6 |
/// <remarks/> public nciicGetCondition() { //验证服务器证书回调自动验证 ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate; } |
from:https://www.cnblogs.com/sufei/archive/2010/03/23/1692811.html
View Details|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
public partial class _404 : System.Web.UI.Page { /// <summary> /// 目标服务器URL /// </summary> private readonly string targetUrl = "目标服务器"; protected void Page_Load(object sender, EventArgs e) { var folderPath = ""; try { // PrintSeverVariables(); // 取出资源地址 var fullUrl = Request.ServerVariables["QUERY_STRING"]; // 全地址 var resourceUrl = Regex.Replace(fullUrl, @"404;https?\://[^/]+", ""); // 取出文件名 var lastMatch = Regex.Match(resourceUrl, @"[^/]+(?!.*\.xlsx?)"); if (!lastMatch.Success || lastMatch.Groups.Count < 1) { Response.StatusCode = 404; return; } var fileName = lastMatch.Groups[0].Value.Split('?')[0]; if (string.IsNullOrEmpty(fileName) || fileName.IndexOf('.') < 0) { Response.StatusCode = 404; return; } // 扩展名 var extensionName = fileName.Split('.')[1].ToLower(); if (extensionName != "xls" && extensionName != "xlsx") // 只拉取excel文件 { Response.StatusCode = 404; return; } // 拉取文件 并保存 using (var stream = Get(targetUrl + resourceUrl)) { // 创建文件夹 folderPath = Server.MapPath(resourceUrl.Replace(fileName, "").Replace("/jq", "")); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } // 保存文件 SaveFile(stream, folderPath + fileName); } // 转向拉取的静态资源 Response.ContentType = "application/octet-stream"; Response.WriteFile(folderPath + fileName); } catch (Exception ex) { Response.StatusCode = 404; return; } } /// <summary> /// 保存文件 /// </summary> /// <param name="stream"></param> /// <param name="fileName"></param> public void SaveFile(Stream stream, string fileName) { // 保存文件 using (var fs = new FileStream(fileName, FileMode.OpenOrCreate)) { stream.CopyTo(fs); fs.Close(); stream.Close(); } } /// <summary> /// Get请求 /// </summary> /// <param name="url"></param> /// <param name="postData"></param> /// <returns></returns> static Stream Get(string url) { //请求 var request = (HttpWebRequest)WebRequest.Create(url); request.Timeout = 600000; // 600秒 request.Method = "GET"; //接收 var response = (HttpWebResponse)request.GetResponse(); return response.GetResponseStream(); } /// <summary> /// 打印环境变量 /// </summary> void PrintSeverVariables() { foreach (string key in Request.ServerVariables) { Response.Write("<b>" + key + ":</b>" + Request.ServerVariables[key] + "<br>"); } } } |
View Details