• [问题求助] 异常处理超过redo_times次数后让RPA结束而不继续
    RPA实现的目的是在两个网页上下载两个文件,具体流程如图所示。对于我现在的实现,“下载A文件”和“下载B文件”,我用了两个Try-Catch语句分别进行异常处理。Try的内容是打开网页并导出文件,Catch的内容是关闭页面和清除下载文件目录。因为网页响应问题,将两个模块中try的redo_times参数设置为3次。我发现当“下载A文件”模块失败了3次以后,RPA会继续执行 “下载B文件”的模块。如果“下载A文件”模块3次都失败了,我想让RPA立刻结束而不是运行到下载B文件的模块,我该如何实现呢?我想着利用try catch后的finally语句,但是在finally语句中我该如何获取try语句的成功状态呢?我想着利用redo_times=0说明3次运行都失败了,但是这个参数好像没有办法获得?另外一种方法是设置一个didDownloadSuccessFlag的标记,默认为False,一旦try文件下载成功,则将其设置为True。然后finally中读取此标记,如果判断为False,则停止机器人,如果使用这种方式,让RPA此时停止运行的语句/控件有哪些呢?希望有人能回答此问题,谢谢你啦。🫡
  • [技术干货] 开源自动化的RPA工具推荐
    开源自动化的RPA工具在近年来得到了广泛的关注和应用,这些工具以软件机器人和人工智能为基础,帮助企业实现业务流程的自动化。以下是一些知名的开源RPA工具及其简要介绍:Robot Framework:Robot Framework是最专业、最先进的开源RPA工具之一。它能够帮助企业经济高效地提供丰富的业务流程自动化服务,支撑组织实施和运行企业级机器人应用程序。Robot Framework能够大大简化业务运营,改善IT基础设施,减少工作量与成本,并提高企业整体灵活性。它还具备良好的可扩展性,能够为企业建立虚拟员工,并很容易地与其他自动化工具集成。Taskt:Taskt(之前称为sharpRPA)是一个免费的、开源的、有趣的流程自动化软件。它提供了易用的操作界面和强大的功能,使得用户可以轻松地创建和管理自动化任务。Aibote:Aibote是由江西爱伯特科技自主研发的一款纯代码RPA办公自动化框架。它支持Android、Browser和Windows三大平台,框架免费,API和接口协议开源。Aibote以socket tcp接口协议通信方式命令驱动,支持任何一门计算机语言调用,为企业提供了极大的灵活性。Automagica:Automagica是一款开源、智能的流程自动化工具,它利用先进的算法和机器学习技术,实现复杂业务流程的自动化。Blue Prism:Blue Prism是一款历史悠久的RPA工具,它拥有由软件机器人驱动的虚拟劳动力,帮助企业实现高效的业务流程自动化。TagUI:TagUI由AI Singapore维护,是RPA的命令行接口,可以在任何操作系统上运行。它使用“flows”概念来表示基于计算机的自动化流程,并强调其语言的简单性或自然性。RPA for Python:RPA for Python是一个面向RPA开发的Python软件包,它基于TagUI构建。该软件包具有网站自动化、计算机视觉自动化、光学字符识别以及键盘鼠标自动化等基本功能。Robocorp:Robocorp是一个相对年轻的开源RPA工具,由风险投资支持的一家初创公司开发。它承诺为开发人员提供强大的RPA解决方案,帮助他们更高效地创建和实施自动化流程。这些开源RPA工具各有特色,适用于不同的场景和需求。在选择工具时,建议根据企业的具体业务需求、技术栈和预算等因素进行综合考虑。同时,由于开源工具可能涉及到持续的更新和维护,因此也需要考虑团队的技术能力和对开源社区的参与度。
  • [问题求助] 基于Python实现基础网络&增值业务中的源代码不存在,请问应该联系谁?
    在这个指导连接中:https://devzone.huawei.com/cn/enterprise/cloudcampus/networkPythonSdk.html点解代码托管,发现源代码丢失出现如下提示:
  • CodeArts 11月常见问题合集
    现在CodeArts Snap可以申请试用吗?现在CodeArts Snap可以申请试用吗?_CodeArts_华为云论坛 (huaweicloud.com)答:申请须知尊敬的华为云开发者,感谢您关注华为云CodeArts Snap。 产品当前处于伙伴邀请测试阶段,暂时不支持开放下载和试用。 您可以填写并提交申请以进入我们的试用候选名单,我们将在未来合适的时机通知您参加试用,恳请您耐心等待。 再次感谢您的关注和理解,祝您工作顺利。codeArts IDE 新建工程没有反应codeArts IDE 新建工程没有反应_CodeArts_华为云论坛 (huaweicloud.com)codearts for c/c++和codearts for java是同一款软件吗?codearts for c/c++和codearts for java是同一款软件吗?_CodeArts_华为云论坛 (huaweicloud.com)答:不是一款软件,针对与不同编程语言的软件无法安装扩展“huaweicloud.java-project-wizard”,因为它与 CodeArts IDE“2.1.1”不兼容无法安装扩展“huaweicloud.java-project-wizard”,因为它与 CodeArts IDE“2.1.1”不兼容_CodeArts_华为云论坛升级 CodeArts IDE:尝试升级你的 CodeArts IDE 到最新版本,以确保与扩展的兼容性。你可以在 CodeArts IDE 的官方网站或者插件市场查找最新版本,并按照它们的文档进行升级。寻找兼容的扩展版本:尝试查找与你当前使用的 CodeArts IDE 版本兼容的 "huaweicloud.java-project-wizard" 扩展的旧版本。你可以在扩展的官方网站、插件市场或者开发者社区中查找该扩展的旧版本,并尝试安装兼容的版本。联系扩展开发者:如果以上方法都无法解决问题,你可以尝试联系 "huaweicloud.java-project-wizard" 扩展的开发者,向他们反馈兼容性问题,并询问是否有计划发布适用于你当前使用的 CodeArts IDE 版本的更新。Couldn't start client SmartAssist JavaCouldn't start client SmartAssist Java_CodeArts_华为云论坛 (huaweicloud.com)检查网络连接:SmartAssist Java 可能需要连接到互联网才能正常工作。确保你的计算机有稳定的网络连接,检查插件是否安装正确:确保 SmartAssist Java 插件已正确安装。有时插件安装不完整或者存在版本兼容性问题会导致这样的错误。清除缓存:尝试清除缓存数据,代码检查中的质量门禁,我应该如何去指定标准是否有指导案例代码检查中的质量门禁,我应该如何去指定标准是否有指导案例_CodeArts_华为云论坛 (huaweicloud.com)代码检查时候我应该如何进行自定义规则?代码检查时候我应该如何进行自定义规则?_CodeArts_华为云论坛 (huaweicloud.com)CodeArts的流水线并发最大能支持到多少?华为云论坛_云计算论坛_开发者论坛_技术论坛-华为云 (huaweicloud.com)CodeArts IDE for Java 插件 java Debug Support 激活失败CodeArts IDE for Java 插件 java Debug Support 激活失败_CodeArts_华为云论坛 (huaweicloud.com)
  • [技术干货] 高性能负载均衡-分类和算法
    高性能集群之所以复杂,主要原因是增加了任务分配器,以及为任务选择合适的分配算法。负载均衡器就是任务分配器,负载均衡这个名称已经成为事实标准,但负载均衡不只是为了计算单元的负载达到均衡状态。分类及架构常见的负载均衡分三种:DNS负载、硬件负载、软件负载1、DNS负载均衡定义:解析同一个域名返回不同的IP地址,一般用来实现地理级别的均衡。例如同样的域名,北方用户和南方用户获取的地址是不一样的。优点:简单、成本低实现就近访问,提升访问速度缺点:更新不及时(DNS缓存时间长)扩展性差(无法根据业务定制和扩展)分配策略简单(算法少、无法感知后端服务器状态)2、硬件负载均衡定义:通过单独的硬件设备实现负载均衡功能,可以理解为一个用于负载均衡的基础网络设备。目前业界典型的硬件负载均衡设备有两款:F5 和 A10。优点:功能强大(支持各层级负载、支持全面的负载算法、支持全局负载)性能强大(支持100万以上并发)稳定性高(商用硬件负载)支持安全防护(具备防火墙、防DDoS攻击等功能)缺点:价格昂贵(起步15万,最高上百万)扩展能力差(硬件设备无法进行扩展和定制)3、软件负载均衡定义:通过负载均衡软件来实现负载均衡功能,常见的有 Nginx 和 LVS两种。优点:简单(部署维护都比较简单)便宜(只需Linux服务器装上软件)灵活(可根据业务方便扩展和定制)缺点(与硬件负载相比):性能一般(一个Nginx大约支撑5万并发)功能没有硬件负载强大一般不具备防火墙和防DDoS等安全功能4、典型架构3种负载机制在实际应用中不是非此即彼,可以组合使用。组合的基本原则为:DNS 负载均衡用于实现地理级别的负载均衡;硬件负载均衡用于实现集群级别的负载均衡;软件负载均衡用于实现机器级别的负载均衡。算法根据算法期望达到的目的,可以分为4类:任务平分类:平均分配,平均可以是数量平均、也可以是比例平均、权重平均负载均衡类:根据服务器负载进行分配,这里的负载指系统当前压力,如CPU负载、连接数、I/O使用率等性能最优类:根据服务器响应时间进行分配,响应最快的分配更多新任务Hash类:根据任务某些关键信息进行Hash运算,结果值相同的分配同一台服务器1、轮询定义:按照顺序轮流分配到服务器,不关注服务器本身运行状态如何。特点:只关注服务器是否在运行,只要运行就分配任务,不管运行是否良好。『简单』是优点,也是缺点。2、加权轮询定义:轮询的特殊形式,根据服务器权重进行任务分配,权重指根据硬件配置进行静态配置的,主要目的是为了解决不同服务器处理能力有差异的问题。特点:解决了轮询算法中无法根据服务器的配置差异进行任务分配的问题,但依然无法根据服务器的状态差异进行任务分配。3、负载最低优先定义:将任务分配给当前负载最低的服务器,这里的当前负载根据不同任务类型和业务,可以用不同指标衡量。如连接数、HTTP请求数、CPU负载、I/O负载等。特点:解决了轮询算法中无法感知服务器状态的问题,代价是增加很多复杂度,因为需要感知服务器当前的运行状态。效果美好但实际应用场景没有轮询多。4、性能最优类定义:站在客户端的角度进行分配,优先将任务分配给处理速度最快的服务器。特点:与负载最低优先类的算法类似,需要感知服务器状态并且在合适周期内进行统计分析,复杂度很高。5、Hash类定义:根据任务中的某些关键信息进行 Hash 运算,将值相同的请求分配到同一台服务器,目的主要是为了满足特定业务需求。常见的有源地址Hash和ID Hash。特点:将同一个源地址或带有某个ID标识的任务分配给同一个服务器,适合于存在事务、会话的业务链接:https://www.jianshu.com/p/dbba5763b30f
  • [技术干货] 运维必备的17个技巧【转】
    1、查找当前目录下所有以.tar结尾的文件然后移动到指定目录:find . -name “*.tar” -exec mv {}./backup/ ;❝注解:find –name 主要用于查找某个文件名字,-exec 、xargs 可以用来承接前面的结果,然后将要执行的动作,一般跟 find 在一起用的很多,find 使用我们可以延伸 -mtime 查找修改时间、-type 是指定对象类型(常见包括 f 代表文件、d代表目录),-size 指定大小,例如经常用到的:查找当前目录30天以前大于100M的LOG文件并删除。find . -name "*.log" –mtime +30 –type f –size +100M | xargs rm –rf {};2、批量解压当前目录下以 .zip 结尾的所有文件到指定目录:for i  in  `find . –name “*.zip”–type f ` do unzip –d $i /data/www/img/ done❝注解:for i in (command); do … done 为 for 循环的一个常用格式,其中I为变量,可以自己指定。3、sed常用命收集:test.txt做测试如何去掉行首的.字符:sed -i ‘s/^.//g’ test.txt在行首添加一个a字符:sed’s/^/a/g’    test.txt在行尾添加一个a字符:sed’s/$/a/‘     tets.txt在特定行后添加一个c字符:sed ‘/wuguangke/ac’ test.txt在行前加入一个c字符:sed’/wuguangke/ic’ test.txt更多sed命令请查阅相关文档。4、如何判断某个目录是否存在,不存在则新建,存在则打印信息。if [! –d /data/backup/];then Mkdir–p /data/backup/ else echo  "The Directory alreadyexists,please exit" fi注解:if…;then …else ..fi:为if条件语句,!叹号表示反义“不存在“,-d代表目录。5、监控linux磁盘根分区,如果根分区空间大于等于90%,发送邮件给Linux SA(1)、打印根分区大小df -h |sed -n '//$/p'|awk '{print $5}'|awk –F ”%” '{print $1}'注解:awk ‘{print $5}’意思是打印第5个域,-F的意思为分隔,例如以%分隔,简单意思就是去掉百分号,awk –F. ‘{print $1}’分隔点.号。(2)、if条件判断该大小是否大于90,如果大于90则发送邮件报警while sleep 5m do for i in `df -h |sed -n '//$/p' |awk '{print $5}' |sed 's/%//g'` do echo $i if [ $i -ge 90 ];then echo “More than 90% Linux of disk space ,Please LinuxSA Check Linux Disk !” |mail -s “Warn Linux / Parts is $i%”  XXX@XXX.XX fi done done6、统计 Nginx 访问日志,访问量排在前20 的 ip地址:cat access.log |awk '{print $1}'|sort|uniq -c |sort -nr |head -20❝注解:sort排序、uniq(检查及删除文本文件中重复出现的行列 )7、sed另外一个用法找到当前行,然后在修改该行后面的参数:sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/configSed冒号方式 sed -i ‘s:/tmp:/tmp/abc/:g’test.txt意思是将/tmp改成/tmp/abc/。8、打印出一个文件里面最大和最小值:cat a.txt |sort -nr|awk ‘{}END{print} NR==1′ cat a.txt |sort -nr |awk ‘END{print} NR==1′这个才是真正的打印最大最小值:sed ‘s/ / /g’ a.txt |sort -nr|sed -n ’1p;$p’9、使用snmpd抓取版本为v2的cacti数据方式:snmpwalk -v2c -c public 192.168.0.24110、修改文本中以jk结尾的替换成yz:sed -e ‘s/jk$/yz/g’ b.txt11、网络抓包:Tcpdumptcpdump -nn host 192.168.56.7 and port 80 抓取56.7通过80请求的数据包。 tcpdump -nn host 192.168.56.7 or ! host 192.168.0.22 and port 80 排除0.22 80端口! tcp/ip 7层协议物理层–数据链路层-网络层-传输层-会话层-表示层-应用层。12、显示最常用的20条命令:cat .bash_history | grep -v ^# | awk ‘{print $1}’ | sort | uniq -c | sort -nr | head-2013、写一个脚本查找最后创建时间是3天前,后缀是*.log 的文件并删除。find . -mtime +3  -name "*.log" |xargs rm -rf {} ;14、写一个脚本将某目录下大于100k的文件移动至/tmp下。find . -size +100k -exec mv {} /tmp ;15、写一个防火墙配置脚本,只允许远程主机访问本机的80端口。iptables -F iptables -X iptables -A INPUT -p tcp --dport 80 -j accept iptables -A INPUT -p tcp -j REJECT或者iptables -A INPUT -m state --state NEW-m tcp -p tcp --dport 80 -j ACCEPT16、写一个脚本进行 Nginx 日志统计,得到访问 IP 最多的前10个(nginx日志路径:/home/logs/nginx/default/access.log)。 cd /home/logs.nginx/default sort -m -k 4 -o access.logok access.1 access.2 access.3 ..... cat access.logok |awk '{print $1}'|sort -n|uniq -c|sort -nr |head -1017、替换文件中的目录sed 's:/user/local:/tmp:g' test.txt或者sed -i 's//usr/local//tmp/g' test.txt链接:https://www.cnblogs.com/cherishthepresent/p/17104566.html
  • [技术干货] 没有Kubernetes怎么玩Dapr?【转】
    Dapr 被设计成一个面向开发者的企业级微服务编程平台,它独立于具体的技术平台,可以运行在“任何地方”。Dapr本身并不提供“基础设施(infrastructure)”,而是利用自身的扩展来适配具体的部署环境。就目前的状态来说,如果希望真正将原生的Dapr应用与生产,只能部署在K8S环境下。虽然Dapr也提供针对Hashicorp Consul的支持,但是目前貌似没有稳定的版本支持。Kubernetes对于很多公司并非“标配”,由于某些原因,它们可以具有一套自研的微服务平台或者弹性云平台,让Dapr与之适配可能更有价值。这两周我们对此作了一些可行性研究,发现这其实不难,记下来我们就同通过一个非常简单的实例来介绍一下大致的解决方案。(拙著《ASP.NET Core 6框架揭秘》热卖中,首印送签名专属书签)。一、NameResolution组件    虽然Dapr提供了一系列的编程模型,比如服务调用、发布订阅和Actor模型等,被广泛应用的应该还是服务调用。我们知道微服务环境下的服务调用需要解决服务注册与发现、负载均衡、弹性伸缩等问题,其实Dapr在这方面什么都没做,正如上面所说,Dapr自身不提供基础设施,它将这些功能交给具体的部署平台(比如K8S)来解决。Dapr中于此相关唯有一个简单得不能再简单的NameResolution组件而已。    从部署的角度来看,Dapr的所有功能都体现在与应用配对的Sidecar上。我们进行服务调用得时候只需要指定服务所在得目标应用的ID(AppID)就可以了。服务请求(HTTP或者gRPC)从应用转到sidecar,后者会将请求“路由”到合适的节点上。如果部署在Kubernetes集群上,如果指定了目标服务的标识和其他相关的元数据(命名空间和集群域名等),服务请求的寻址就不再是一个问题。实际上NameResolution组件体现的针对“名字(Name)”的“解析(Resolution)”解决的就是如将Dapr针对应用的标识AppID转换成基于部署环境的应用标识的问题。从dapr提供的代码来看,它目前注册了如下3种类型的NameResolution组件:mdns:利用mDNS(Multicast DNS)实现服务注册与发现,如果没有显式配置,默认使用的就是此类型。由于mDNS仅仅是在小规模网络中采用广播通信实现的一种DNS,所以根本不适合正式的生成环境。kubernetes:适配Kubernetes的名字解析,目前提供稳定的版本。consul: 适配HashiCorp Consul的名字解析,目前最新为Alpha版本。二、Resolver    一个注册的NameResolution组件旨在提供一个Resolver对象,该对象通过如下的接口来表示。如下面的代码片段所示,Resolver接口提供两个方法,Init方法会在应用启动的时候调用,作为参数的Metadata会携带于当前应用实例相关的元数据(包括应用标识和端口,以及Sidecar的HTTP和gRPC端口等)和针对当前NameResolution组件的配置。对于每一次服务调用,目标应用标识和命名空间等相关信息会被Sidecar封装成一个ResolveRequest 接口,并最为参数调用Resolver对象的ReolveID方法,最终得到一个于当前部署环境相匹配的表示,并利用此标识借助基础设施的利用完整目标服务的调用。package nameresolution type Resolver interface { Init(metadata Metadata) error ResolveID(req ResolveRequest) (string, error) } type Metadata struct { Properties map[string]string `json:"properties"` Configuration interface{} } type ResolveRequest struct { ID string Namespace string Port int Data map[string]string }三、模拟服务注册与负载均衡    假设我们具有一套私有的微服务平台,实现了基本的服务注册、负载均衡,甚至是弹性伸缩的功能,如果希望在这个平台上使用Dapr,我们只需要利用自定义的NameResolution组件提供一个对应的Resolver对象就可以了。我们利用一个ASP.NET Core MVC应用来模拟我们希望适配的微服务平台,如下这个HomeController利用静态字段_applications维护了一组应用和终结点列表(IP+端口)。对于针对某个应用的服务调用,我们通过轮询对应终结点的方式实现了简单的负载均衡。便于后面的叙述,我们将该应用简称为“ServiceRegistry”。public class HomeController: Controller { private static readonly ConcurrentDictionary<string, EndpointCollection> _applications = new(); [HttpPost("/register")] public IActionResult Register([FromBody] RegisterRequest request) { var appId = request.Id; var endpoints = _applications.TryGetValue(appId, out var value) ? value : _applications[appId] = new(); endpoints.TryAdd(request.HostAddress, request.Port); Console.WriteLine($"Register {request.Id} =>{request.HostAddress}:{request.Port}"); return Ok(); } [HttpPost("/resolve")] public IActionResult Resolve([FromBody] ResolveRequest request) { if (_applications.TryGetValue(request.ID, out var endpoints) && endpoints.TryGet(out var endpoint)) { Console.WriteLine($"Resolve app {request.ID} =>{endpoint}"); return Content(endpoint!); } return NotFound(); } } public class EndpointCollection { private readonly List<string> _endpoints = new(); private int _index = 0; private readonly object _lock = new(); public bool TryAdd(string ipAddress, int port) { lock (_lock) { var endpoint = $"{ipAddress}:{port}"; if (_endpoints.Contains(endpoint)) { return false; } _endpoints.Add(endpoint); return true; } } public bool TryGet(out string? endpoint) { lock (_lock) { if (_endpoints.Count == 0) { endpoint = null; return false; } _index++; if (_index >= _endpoints.Count) { _index = 0; } endpoint = _endpoints[_index]; return true; } } }HomeController提供了两个Action方法,Register方法用来注册应用,自定义Resolver的Init方法会调用它。另一个方法Resolve则用来完成根据请求的应用表示得到一个具体的终结点,自定义Resolver的ResolveID方法会调用它。这两个方法的参数类型RegisterRequest和ResolveRequest定义如下,后者和前面给出的同名接口具有一致的定义。两个Action都会在控制台输出相应的文字显示注册的应用信息和解析出来的终结点。public class RegisterRequest { public string Id { get; set; } = default!; public string HostAddress { get; set; } = default!; public int Port { get; set; } } public class ResolveRequest { public string ID { get; set; } = default!; public string? Namespace { get; set; } public int Port { get; } public Dictionary<string, string> Data { get; } = new(); }四、自定义NameResolution组件    由于Dapr并不支持组件的动态注册,所以我们得将其源代码拉下来,修改后进行重新编译。这里涉及到两个git操作,dapr和components-contrib,前者为核心运行时,后者为社区驱动贡献得组件。我们将克隆下来的源代码放在同一个目录下。 我们将自定义的NameResolution组件命名为“svcreg”(服务注册之意),所我们在components-contrib/nameresolution目录(该目录下我们会看到上面提到的几种NameResolution组件的定义)下创建一个同名的目录,并组件代码定义在该目录下的svcreg.go文件中。如下所示的就是该NameResolution组件的完整定义。package svcreg import ( "bytes" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "strconv" "github.com/dapr/components-contrib/nameresolution" "github.com/dapr/kit/logger" ) type Resolver struct { logger logger.Logger registerEndpoint string resolveEndpoint string } type RegisterRequest struct { Id, HostAddress string Port int64 } func (resolver *Resolver) Init(metadata nameresolution.Metadata) error { var endpoint, appId, hostAddress string var ok bool // Extracts register & resolve endpoint if dic, ok := metadata.Configuration.(map[interface{}]interface{}); ok { endpoint = fmt.Sprintf("%s", dic["endpointAddress"]) resolver.registerEndpoint = fmt.Sprintf("%s/register", endpoint) resolver.resolveEndpoint = fmt.Sprintf("%s/resolve", endpoint) } if endpoint == "" { return errors.New("service registry endpoint is not configured") } // Extracts AppID, HostAddress and Port props := metadata.Properties if appId, ok = props[nameresolution.AppID]; !ok { return errors.New("AppId does not exist in the name resolution metadata") } if hostAddress, ok = props[nameresolution.HostAddress]; !ok { return errors.New("HostAddress does not exist in the name resolution metadata") } p, ok := props[nameresolution.DaprPort] if !ok { return errors.New("DaprPort does not exist in the name resolution metadata") } port, err := strconv.ParseInt(p, 10, 32) if err != nil { return errors.New("DaprPort is invalid") } // Register service (application) var request = RegisterRequest{appId, hostAddress, port} payload, err := json.Marshal(request) if err != nil { return errors.New("fail to marshal register request") } _, err = http.Post(resolver.registerEndpoint, "application/json", bytes.NewBuffer(payload)) if err == nil { resolver.logger.Infof("App '%s (%s:%d)' is successfully registered.", request.Id, request.HostAddress, request.Port) } return err } func (resolver *Resolver) ResolveID(req nameresolution.ResolveRequest) (string, error) { // Invoke resolve service and get resolved target app's endpoint ("{ip}:{port}") payload, err := json.Marshal(req) if err != nil { return "", err } response, err := http.Post(resolver.resolveEndpoint, "application/json", bytes.NewBuffer(payload)) if err != nil { return "", err } defer response.Body.Close() result, err := ioutil.ReadAll(response.Body) if err != nil { return "", err } return string(result), nil } func NewResolver(logger logger.Logger) *Resolver { return &Resolver{ logger: logger, } }     如上面的代码片段所示,我们定义核心的Resolver结构,该接口除了具有一个用来记录日志的logger字段,还有两个额外的字段registerEndpoint和resolveEndpoint,分别代表ServiceRegistry提供的两个API的URL。在为Resolver结构实现的Init方法中,我们从作为参数的元数据中提取出配置,并进一步从配置中提取出ServiceRegistry的地址,并在此基础上添加路由路径“/register”和“/resolve”对Resolver结构的registerEndpoint和resolveEndpoint字段进行初始化。接下来我们从元数据中提取出AppID、IP地址和内部gRPC端口号(外部应用通过此端口调用当前应用的Sidecar),它们被封装成RegisterRequest结构之后被序列化成JSON字符串,并作为输入调用对应的Web API完成对应的服务注册。    在实现的ResolveID中,我们直接将作为参数的ResolveRequest结构序列化成JSON,调用Resolve API。响应主体部分携带的字符串就是为目标应用解析出来的终结点(IP+Port),我们直接将其作为ResolveID的返回值。五、注册自定义NameResolution组件    自定义的NameResolution组件需要显式注册到代表Sidecar的可以执行程序daprd中,入口程序所在的源文件为dapr/cmd/daprd/main.go。我们首先按照如下的方式导入svcreg所在的包”github.com/dapr/components-contrib/nameresolution/svcreg”。// Name resolutions. nr "github.com/dapr/components-contrib/nameresolution" nr_consul "github.com/dapr/components-contrib/nameresolution/consul" nr_kubernetes "github.com/dapr/components-contrib/nameresolution/kubernetes" nr_mdns "github.com/dapr/components-contrib/nameresolution/mdns" nr_svcreg "github.com/dapr/components-contrib/nameresolution/svcreg"    在main函数中,我们找到用来注册NameResolution组件的那部分代码,按照其他NameResolution组件注册那样,依葫芦画瓢完成针对svcreg的注册即可。注册代码中用来提供Resolver的NewResolver函数定义在上述的svcreg.go文件中。runtime.WithNameResolutions( nr_loader.New("svcreg", func() nr.Resolver { return nr_svcreg.NewResolver(logContrib) }), nr_loader.New("mdns", func() nr.Resolver { return nr_mdns.NewResolver(logContrib) }), nr_loader.New("kubernetes", func() nr.Resolver { return nr_kubernetes.NewResolver(logContrib) }), nr_loader.New("consul", func() nr.Resolver { return nr_consul.NewResolver(logContrib) }), ),六、编译部署daprd.exe    到目前为止,所有的编程工作已经完成,接下来我们需要重新编译代表Sidecar的daprd.exe。从上面的代码片段可以看出,dapr的包路径都以“github.com/dapr”为前缀,所以我们需要修改go.mod文件(dapr/go.mod)将依赖路径重定向到本地目录,所以我们按照如下的方式添加了针对“github.com/dapr/components-contrib”的替换规则。replace ( go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0 gopkg.in/couchbaselabs/gocbconnstr.v1 => github.com/couchbaselabs/gocbconnstr v1.0.5 k8s.io/client => github.com/kubernetes-client/go v0.0.0-20190928040339-c757968c4c36 github.com/dapr/components-contrib => ../components-contrib  在将当前目录切换到“dapr/cmd/daprd/”后,以命令行的方式执行“go build”后会在当前目录下生成一个daprd.exe可执行文件。现在我们需要使用这个新的daprd.exe将当前使用使用的替换掉,该文件所在的目录在“%userprofile%.dapr\bin”。七、配置svcreg    我们之间已经说过,Dapr默认使用的是基于mDNS的NameResolution组件(对于的注册名为为“mdns”)。若要使我们自定义的组件“svcreg”生效,需要修改Dapr的配置文件(%userprofile%.dapr\config.yaml)。如下面的代码片段所示,我们不仅将使用的组件名称设置为“svcreg”(在dapr/cmd/daprd/main.go中注册NameResolution组件时提供的名称),还将服务注册API的URL(http://127.0.0.1:3721)放在了配置中(Resolver的Init方法提取的URL就来源于这里)。apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: daprConfig spec: nameResolution: component: "svcreg" configuration: endpointAddress: http://127.0.0.1:3721 tracing: samplingRate: "1" zipkin: endpointAddress: http://localhost:9411/api/v2/spans八、测试效果    我们现在编写一个Dapr应用来验证一下自定义的NameResolution组件是否有效。我们采用《ASP.NET Core 6框架揭秘实例演示[03]:Dapr初体验》提供的服务调用的例子。具有如下定义的App2是一个ASP.NET Core应用,它利用路由提供了用来进行加、减、乘、除运算的API。 using Microsoft.AspNetCore.Mvc; using Shared; var app = WebApplication.Create(args); app.MapPost("{method}", Calculate); app.Run("http://localhost:9999"); static IResult Calculate(string method, [FromBody] Input input) { var result = method.ToLower() switch { "add" => input.X + input.Y, "sub" => input.X - input.Y, "mul" => input.X * input.Y, "div" => input.X / input.Y, _ => throw new InvalidOperationException($"Invalid method {method}") }; return Results.Json(new Output { Result = result }); } public class Input { public int X { get; set; } public int Y { get; set; } } public class Output { public int Result { get; set; } public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.Now; }具有如下定义的App1是一个控制台程序,它利用Dapr客户端SDK调用了上诉四个API。 using Dapr.Client; using Shared; HttpClient client = DaprClient.CreateInvokeHttpClient(appId: "app2"); var input = new Input(2, 1); await InvokeAsync("add", "+"); await InvokeAsync("sub", "-"); await InvokeAsync("mul", "*"); await InvokeAsync("div", "/"); async Task InvokeAsync(string method, string @operator) { var response = await client.PostAsync(method, JsonContent.Create(input)); var output = await response.Content.ReadFromJsonAsync<Output>(); Console.WriteLine( $"{input.X} {@operator} {input.Y} = {output.Result} ({output.Timestamp})");   在启动ServiceRegistry之后,我们启动App2,控制台上会阐述如下的输出。从输出的NameResolution组件名称可以看出,我们自定义的svcreg正在被使用。由于应用启动的时候会调用Resolver的Init方法进行注册,这一点也反映在ServiceRegistry如下所示的输出上。可以看出注册实例的AppID为”app2”,对应的终结点为“10.181.22.4:60840”。然后我们再启动App1,如下所示的输出表明四次服务调用均成功完成。启动的App1的应用实例同样会在ServiceRegistry中注册。而四次服务调用会导致四次针对Resolver的ResolveID方法的调用,这也体现在ServiceRegistry的输出上。链接:https://www.cnblogs.com/artech/p/dapr-custom-name-resolution.html
  • 如何加速 Web 应用程序并提高网站性能【转】
    我们不需要提醒你快速网站加载的重要性。要么是 3 秒,要么是用户离开,因此你必须优化网站性能以符合用户的期望。网站性能的优化是一件大事。它涉及多个方面需要照顾,其中许多取决于网站本身、其复杂性和元素。但是,还有一些适用于任何站点的常用优化方法。集成 CDN内容交付网络(又名 CDN)是一个非常棒的工具,可以集成到你的网站中,因为它可以大大加快你的内容交付速度。因为它是一个分布式服务器网络,所以 CDN 会找到离用户最近的服务器并部署它来交付内容。通过这种方式,内容会走得更短,并提供更好的用户体验。许多 CDN 还具有许多其他可提高网站性能的功能:图像优化、缩小 CSS、代码重组。压缩文件每个文件都需要一些时间来加载。问题是,文件越大,加载的时间就越长。结果,该网站以极其缓慢的方式加载并惹恼了用户。解决大体积文件的问题,压缩它们并享受更快的性能!对于文件压缩,建议使用 Gzip 工具,这是最受信任的工具之一。Gzip 声称可以将文件大小减少多达 70%,并显着提高性能。启用 Gzip 的方法有很多种,具体取决于你的站点。 例如,你可以在 .htaccess 文件中启用 Gzip 或简单地使用插件。使用延迟加载每个网站都包含一定数量的媒体文件(即图像、视频、音频文件),每个元素的加载需要相当长的时间。延迟加载设计模式使媒体文件仅在进入用户视点时才加载。这意味着,当用户打开页面时,它不会立即加载所有媒体文件,而只会加载页面顶部的媒体文件。而且,当用户向下滚动时,页面将加载更多文件。这种技术极大地节省了带宽,同时提供了无缝的用户体验。延迟加载还摆脱了不必要的代码执行并减少了内存使用。你还可以将代码分成不同的包,以便不同的页面仅包含代码块。这样,浏览器将只加载用户所在的那些代码。缩小 CSS 和 JavaScript当你的站点下载 JavaScript 或 CSS 文件时,会向服务器发送一个 HTTP 请求。发送的请求越多,性能就越慢。为了解决这个问题,你可以合并和缩小文件以减少 HTTP 请求的数量,从而提高性能。缩小包括消除空格、不必要的代码行或换行符。要执行此过程,请使用 WP Rocket 或 WillPeavy 等可用插件之一。优化数据库数据库优化可能是你网站性能的瓶颈。虽然有很多方面需要关注,但最常见的是:MySQL 查询优化:使用 EverSQL 查询优化器等工具来微调 MySQL 查询并获得有用的建议,索引:该方法允许更快的行选择和排序,内存容量:如果内存不足,会降低性能,因此你可能需要寻找更强大的托管解决方案。请注意,数据库优化也取决于你的站点。 对于某些网站(即电子商务平台),有一些独特的问题需要处理,因此你需要先进行审核,以确定所有需要优化的问题区域。摆脱阻塞的 JavaScript许多网站最常见的问题之一是阻止渲染的 JavaScript 文件。 要解决此问题,你可以执行以下操作:在 HTML 文档中内联外部锁定脚本使用特殊插件(即 W3 Total Cache)使用 async 属性使 JavaScript 文件异步启用缓存每次用户登陆页面时,浏览器都会加载其内容 - 每次出现新查询时都会这样做。 现在,你能想象每天有多少用户访问你的网站以及浏览器必须加载页面内容的次数吗?为了防止站点为返回的用户加载相同的内容并节省一些加载时间,请启用浏览器缓存。 至于新用户,网站仍会从头开始加载内容,因为新用户的缓存是空的。尽管如此,完整的浏览器缓存可以将站点速度从 2.6 毫秒提高到 1(甚至 0.9),因此强烈建议使用它。快速工具:盖茨比Gatsby 是一个静态站点生成器。 该框架使用初步加载:当用户打开主页时,浏览器在后台模式下加载显示链接到主页的站点其他页面所需的数据。使用 Gatsby 构建的网站是一个 React 应用程序,因此它只加载有关页面之间差异的数据,而不是完整的页面。 在页面之间的转换过程中,虚拟 DOM 被更新。 通过这种方式,用户可以享受高速加载和流畅的网站性能。上述性能优化方法是处理网站慢问题的最常用方法。但是,由于每个网站和 Web 应用程序都是独一无二的,因此你需要首先进行性能审核,以准确识别你的网站存在的问题并提出解决问题的正确方法。原文链接:cid:link_0
  • [技术干货] 掌握Web应用的监控与告警【转】
    监控最重要的是在故障发生时,能将告警信息发送出来,让正确的人第一时间获悉故障的详情,只有这样才能尽快排除故障。企业微信很多公司都有使用,而且Alertmanager支持将企业微信作为告警通道。最近组里又来了一个需求:当告警发生时,将告警信息通过企业微信发送给开发的相关负责人,方便尽快排除故障。实际使用Alertmanager来完成这项工作,下面介绍具体的实现方法。详细配置告警通道配置监控最重要的是在故障发生时,能将告警信息发送出来,让正确的人第一时间获悉故障的详情,只有这样才能尽快排除故障。企业微信很多公司都有使用,而且Alertmanager支持将企业微信作为告警通道。按照企业微信的官方文档来配置告警通道,如果觉得麻烦,可以在浏览器上搜索“alertmanager 企业微信”关键字,就有很多配置例子展示。我们需要得到下面五个键值对:wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'wechat_api_corp_id: '12345678'agent_id: 12345678api_secret: 12345678to_tag: 4这五个键值对需要在Alertmanager中配置,后面四个键的值根据实际情况填写。企业微信有三种ID来选择消息的接收对象:用户ID、部门ID和标签ID。因为第三种方式支持同时包含用户和部门,使用起来比较灵活,这里选择第三种方式。点击“标签详情”,可以看到标签ID,在配置Alertmanager时会用到。Blackbox配置这里直接将配置文件贴出。docker-compose.yaml:version: '3.3'services: blackbox_exporter: image: prom/blackbox-exporter:v0.19.0 ports: - "9115:9115" restart: always volumes: - "./config:/config" command: "--config.file=/config/blackbox.yaml"config/blackbox.yaml:modules: http_get: prober: http timeout: 5s http: valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] valid_status_codes: [200] no_follow_redirects: false tls_config: insecure_skip_verify: trueAlertmanager配置这里是关键,因为告警通知的发送控制都由Alertmanager来控制。配置文件如下。docker-compose.yaml:alertmanager: image: bitnami/alertmanager:0 restart: "always" ports: - 9093:9093 container_name: "alertmanager" volumes: - "./config:/etc/alertmanager"config/config.yml:global: resolve_timeout: 5m wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' wechat_api_corp_id: '1234567'templates: - '/etc/alertmanager/*.tmpl'route: receiver: wechat group_wait: 1s group_interval: 1s repeat_interval: 2s group_by: [adm] routes: - matchers: - adm="search" receiver: searchEngine group_wait: 10s - matchers: - adm="portalweb" receiver: portalWeb group_wait: 10sreceivers:- name: wechat wechat_configs: - to_tag: infra message: '{{ template "wechat.message" . }}' agent_id: 1000002 message_type: markdown api_secret: verylongstring- name: searchEngine wechat_configs: - to_tag: searchdep message: '{{ template "wechat.message" . }}' agent_id: 1000002 message_type: markdown api_secret: verylongstring- name: portalWeb wechat_configs: - to_tag: portalwebdep message: '{{ template "wechat.message" . }}' agent_id: 1000002 message_type: markdown api_secret: verylongstring有几个参数需要介绍下:group_wait:Alertmanager 在接收到一条新的告警(第一次出现的告警)时,将这条告警发送给 receiver 之前需要等待的时间。group_interval:对于一条已经出现过的告警,alertmanager 每隔 group_interval 时间检查一次告警。repeat_interval: 对于一条已经出现过的告警,每隔 repeat_interval 会重新发送给 receiver。有篇文档整理得很好,这里直接列出来。“Alertmanager 在收到一条新的告警之后,会等待 group_wait 时间,对这条新的告警做一些分组、更新、静默的操作。当第一条告警经过 group_wait 时间之后,Alertmanager 会每隔 group_interval 时间检查一次这条告警,判断是否需要对这条告警进行一些操作,当 Alertmanager 经过 n 次 group_interval 的检查后,n*group_interval 恰好大于 repeat_interval 的时候,Alertmanager 才会将这条告警再次发送给对应的 receiver。”文中这三个参数配置的值很小,主要为测试目的,生产环境根据需要配置。还有一点需要注意,Alertmanager子路由(即routes里面)中配置的参数会覆盖根路由(即route里面)中配置的参数,所以按照文件“config/config.yml”中的配置,如果一条告警发送到了“searchEngine”,就不可能再发送给默认的接收者“wechat”,除非子路由没有匹配。告警模板文件:config/wechat.tmpl。{{ define "wechat.message" }}{{- if gt (len .Alerts.Firing) 0 -}}{{- range $index, $alert := .Alerts -}}{{- if eq $index 0 -}}# 报警项: {{ $alert.Labels.alertname }}{{- end }}> `**===告警详情===**` > 告警级别: {{ $alert.Labels.severity }}> 告警详情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>> 故障时间: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>> 故障实例: <font color="info">{{ $alert.Labels.instance }}</font>{{- end }}{{- end }}{{- if gt (len .Alerts.Resolved) 0 -}}{{- range $index, $alert := .Alerts -}}{{- if eq $index 0 -}}# 恢复项: {{ $alert.Labels.alertname }}{{- end }}> `===恢复详情===` > 告警级别: {{ $alert.Labels.severity }}> 告警详情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>> 故障时间: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>> 恢复时间: <font color="warning">{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>> 故障实例: <font color="info">{{ $alert.Labels.instance }}</font>{{- end }}{{- end }}{{- end }}其中语句“{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}”是将时间转换成北京时间,否则默认显示的是UTC时间,不利于故障发生时间的查看。配置完Alertmanager,再看Prometheus的配置。Prometheus配置Prometheus需要增加告警规则文件,所有待监控的metrics都保存在Prometheus中,但它并不知道metrics的值处于什么状态的情况下,自己要发告警给Alertmanager,所以要通过增加告警规则文件告知Prometheus,各个配置文件如下,docker-compose.yaml:version: '3.3'services: prometheus: image: prom/prometheus restart: always ports: - "9090:9090" volumes: - "./config:/config" command: --config.file=/config/prometheus.yamlPrometheus的配置文件,config/prometheus.yaml:# my global configglobal: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s).# Alertmanager configurationalerting: alertmanagers: - static_configs: - targets: - 192.168.52.128:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.rule_files: - /config/alerts.rules # A scrape configuration containing exactly one endpoint to scrape:# Here it's Prometheus itself.scrape_configs: - job_name: 'web-monitor' scrape_interval: 1m metrics_path: /probe params: module: [http_get] static_configs: - targets: - https://www.baidu.com - https://cn.bing.com labels: adm: "search" - targets: - https://www.163.com - https://www.ifeng.com labels: adm: "portalweb" relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: 192.168.52.128:9115 # The blackbox exporter's real hostname:port.Prometheus的告警规则文件,config/alerts.rules:groups: - name: Web监控 rules: - alert: Web API不能访问 expr: probe_success == 0 for: 10s labels: severity: 非常严重 annotations: summary: "{{$labels.instance}}:链接不能访问" description: "{{$labels.instance}}:链接超过10s无法连接"到这里,所有的配置已经完成,看下效果:效果展示在Prometheus上查看probe_success metric的值,看到此时链接“https://www.163.com”访问异常(当然不是真的有问题,可以使用一些手段模拟)。查看Alertmanager Web界面,也收到了Prometheus发送过来的告警信息。企业微信告警信息如下。原文链接:cid:link_0
  • [技术干货] 一条有逼格的Linux命令:实用性极强【转】
    btop命令是一个在Linux系统中查看进程信息的命令,它的概念、起源、发展与现状如下:一、概念btop命令是一个交互式的、实时的、以表格形式展示进程信息的命令行工具。它可以显示当前正在运行的进程列表,包括进程ID、CPU使用率、内存使用率、磁盘I/O等。btop命令还提供了交互式的界面,用户可以通过键盘上的方向键和Page Up/Page Down键来浏览进程列表,以及通过鼠标点击来选择进程进行查看或操作。二、起源btop命令最初是由一个名为Brian K. Jones的开发者创建的,他在使用top命令时发现了一些不满足需求的地方。top命令虽然可以实时查看进程信息,但是它的界面比较简单,无法满足一些用户的需求。因此,Brian K. Jones决定开发一个新的进程查看工具,这就是btop命令的起源。三、发展与现状btop命令自诞生以来,经历了多个版本的发展和改进。随着Linux系统的普及和技术的不断发展,btop命令的功能和性能也不断得到提升。目前,btop命令已经成为一个功能强大、稳定可靠的进程查看工具,被广泛应用于Linux系统中。四、特点与优势相比于其他的进程查看工具,btop命令具有以下特点和优势:交互式界面:btop命令提供了交互式的界面,用户可以通过键盘和鼠标进行操作,更加方便快捷。而其他类似的工具如top、htop等,虽然也提供了实时的进程信息查看功能,但它们的界面相对简单,操作相对较少。实时更新:btop命令可以实时更新进程信息,使得用户可以随时查看最新的进程状态。而其他类似的工具在查看过程中会有一些延迟。自定义显示:btop命令支持自定义显示进程信息,用户可以通过设置选项来选择需要显示的进程信息列和排序方式。而其他类似的工具的显示方式比较固定,无法进行自定义。多进程查看:btop命令支持同时查看多个进程的信息,用户可以通过选择不同的进程进行查看和比较。而其他类似的工具只能查看当前正在运行的进程信息。更好的性能:btop命令在性能方面比其他类似的工具更胜一筹,它可以更快地加载和显示进程信息,而且在处理大量进程信息时也不会出现卡顿的情况。简洁的界面:与其他类似工具相比,btop界面更为简洁,能够显示更多有用的信息。同时,它还支持过滤功能,可以快速查找特定进程。强大的功能:btop不仅提供了基本的进程查看功能,还支持杀死进程、终止进程等操作。此外,它还支持排序功能,可以根据CPU占用率、内存占用率等指标对进程进行排序。可定制性:与其他类似工具相比,btop的可定制性更高。用户可以通过修改配置文件或使用命令行选项来定制界面风格、显示内容等。这使得btop更加灵活和适应不同的使用场景。国际化支持:btop具有良好的国际化支持,可以显示不同语言的进程信息。同时,它还支持多种时区,可以根据用户所在地的时区来显示时间信息。与其他工具集成:btop可以与其他Linux系统工具集成,如与网络监视工具iftop集成,方便用户查看网络流量情况;与系统监控工具htop集成,方便用户查看系统资源使用情况等。这种集成使得btop成为一个功能强大的系统监控工具箱的一部分。五、安装方式红帽系Linux用yum或dnf安装即可。其他Linux发行版安装方式如下。# 下载压缩包wget https://github.com/aristocratos/btop/releases/download/v1.2.13/btop-x86_64-linux-musl.tbz# 下载解压工具yum install bzip2 -y# 解压bunzip2 btop-x86_64-linux-musl.tbztar xf btop-x86_64-linux-musl.tar# 进入解压后的文件夹,进行安装cd btop# 指定安装的目录make install PREFIX=/opt/btop# 运行/opt/btop/bin/btop六、常规操作btop是一个交互式的、实时的、以表格形式展示进程信息的命令行工具,提供了许多常用的操作。以下是一些btop页面中的常用操作:1.键盘操作:使用键盘上的方向键来浏览进程列表。按“r”键,输入刷新间隔,改变屏幕刷新频率。2.筛选进程:使用数字键选择要查看的进程ID(PID)。按“s”键,根据CPU使用率对进程进行排序。按“m”键,根据内存使用率对进程进行排序。按“d”键,列出数据库节点的数据库监视信息。3.查看进程详细信息:鼠标悬停在进程行上,可以查看该进程的详细信息。按“Tab”键,查看绝对值(ABSOLUTE)、平均值(AVERAGE)、差值(DELTA)三个模式中的进程信息。4.终止进程:在进程列表中选择要终止的进程,按“k”键,输入进程ID(PID)并确认终止。5.搜索进程:按“/”键,输入要搜索的进程名称或关键字,按回车键进行搜索。6.设置显示选项:按“o”键,可以设置显示选项,如是否显示线程、内存使用情况等。7.查看系统资源使用情况:按“1”键,可以查看CPU使用率、内存使用率等系统资源使用情况。8.查看数据库监控信息:按“2”键,可以查看数据库监控信息,如数据库节点会话、集合空间等。9.查看系统资源统计信息:按“3”键,可以查看系统资源统计信息,如磁盘I/O、网络流量等。10.查看系统负载信息:按“4”键,可以查看系统负载信息,如系统平均负载、进程状态等。11.查看网络监视信息:按“5”键,可以查看网络监视信息,如网络连接状态、网络流量等。原文链接:cid:link_0
  • [技术干货] Nginx反向代理负载均衡【转】
    介绍: Ngin x是一个高性能的http和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,特点:占有内存少,并发能力强。作为中间件具有如下功能:1、制作静态页面2、反向代理3、负载均衡4、动静分离5、会话保持 ​负载均衡的三种方式  负载均衡有三种部署方式:路由模式、桥接模式、服务直接返回模式。路由模式部署灵活,约60%的用户采用这种方式部署;桥接模式不改变现有的网络架构;服务直接返回(DSR)比较适合吞吐量大特别是内容分发的网络应用。约30%的用户采用这种模式。  1、路由模式(推荐)  路由模式的部署方式,服务器的网关必须设置成负载均衡机的LAN口地址,且与WAN口分署不同的逻辑网络。因此所有返回的流量也都经过负载均衡。这种方式对网络的改动小,能均衡任何下行流量。  2、桥接模式  桥接模式配置简单,不改变现有网络。负载均衡的WAN口和LAN口分别连接上行设备和下行服务器。LAN口不需要配置IP(WAN口与LAN口是桥连接),所有的服务器与负载均衡均在同一逻辑网络中。  由于这种安装方式容错性差,网络架构缺乏弹性,对广播风暴及其他生成树协议循环相关联的错误敏感,因此一般不推荐这种安装架构。  3、服务直接返回模式  这种安装方式负载均衡的LAN口不使用,WAN口与服务器在同一个网络中,互联网的客户端访问负载均衡的虚IP(VIP),虚IP对应负载均衡机的WAN口,负载均衡根据策略将流量分发到服务器上,服务器直接响应客户端的请求。因此对于客户端而言,响应他的IP不是负载均衡机的虚IP(VIP),而是服务器自身的IP地址。也就是说返回的流量是不经过负载均衡的。因此这种方式适用大流量高带宽要求的服务。  接下来就用nginx来实操一下反向代理!!!!  1、WEB服务器环境准备  准备5台服务器  2、环境配置  1.克隆HA1/HA2/WEB1/WEB2/WEB3  2.开机启动 - 修改主机名字 - IP地址 - 修改软件源 - yum cache  3.WEB构建完毕-apache HA1主机配置[root@localhost ~]# hostnamectl set-hostname HA1 && bash[root@ha1 ~]# mkdir /etc/yum.repos.d/bak[root@ha1 ~]# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/[root@ha1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum clean all && yum makecache[root@ha1 html]# systemctl stop firewalld.service && systemctl disable firewalld.serviceHA2主机配置[root@localhost ~]# hostnamectl set-hostname HA2 && bash[root@ha2 ~]# mkdir /etc/yum.repos.d/bak[root@ha2 ~]# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/[root@ha2 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum clean all && yum makecache[root@ha2 html]# systemctl stop firewalld.service && systemctl disable firewalld.serviceweb1[root@localhost ~]# hostnamectl set-hostname web1 && bash[root@web1 ~]# mkdir /etc/yum.repos.d/bak[root@web1 ~]# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/[root@web1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum clean all && yum makecache[root@web1 ~]# systemctl stop firewalld.service && systemctl disable firewalld.service[root@web1 ~]# yum install -y httpd[root@web1 ~]# echo "web-server1" >> /var/www/html/index.html[root@web1 ~]# systemctl start httpd.service && systemctl enable httpd.service && systemctl status httpd.serviceweb2[root@localhost ~]# hostnamectl set-hostname web2 && bash[root@web2 ~]# mkdir /etc/yum.repos.d/bak[root@web2 ~]# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/[root@web2 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum clean all && yum makecache[root@web2 ~]# systemctl stop firewalld.service && systemctl disable firewalld.service[root@web2 ~]# yum install -y httpd[root@web2 ~]# echo "web-server1" >> /var/www/html/index.html[root@web2 ~]# systemctl start httpd.service && systemctl enable httpd.service && systemctl status httpd.serviceweb3[root@localhost ~]# hostnamectl set-hostname web3 && bash[root@web3 ~]# mkdir /etc/yum.repos.d/bak[root@web3 ~]# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/[root@web3 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && yum clean all && yum makecache[root@web3 ~]# systemctl stop firewalld.service && systemctl disable firewalld.service[root@web3 ~]# yum install -y httpd[root@web3 ~]# echo "web-server1" >> /var/www/html/index.html[root@web3 ~]# systemctl start httpd.service && systemctl enable httpd.service && systemctl status httpd.service 3、Nginx软件部署(只在两个HA节点上部署)  HA1  安装nginx软件 [root@ha1 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo[root@ha1 ~]# yum install -y nginx nginx-mod-stream[root@ha1 ~]# systemctl daemon-reload && systemctl start nginx && systemctl enable nginx && systemctl status nginx [root@ha1 ~]# pstree -ap | grep -v grep | grep -i nginx |-nginx,10687 | |-nginx,10688 | `-nginx,10689 [root@ha1 ~]# netstat -nltp | grep -i nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10687/nginx: master tcp6 0 0 :::80 :::* LISTEN 10687/nginx: masterNginx反向代理-负载均衡部署[root@ha1 ~]# cd /etc/nginx/[root@ha1 nginx]# mv nginx.conf nginx.conf.bak修改配置文件[root@ha1 nginx]# vim nginx.conf# For more information on configuration, see:# * Official English Documentation: http://nginx.org/en/docs/# * Official Russian Documentation: http://nginx.org/ru/docs/user nginx;worker_processes auto;error_log /var/log/nginx/error.log;# [alert] 18037#0: 1024 worker_connections are not enoughpid /run/nginx.pid;# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events {worker_connections 1024; # 最多可以建这么多工作节点}##### add to config start #####stream {log_format main '$remote_addr $upstream_addr - [$time_local] $status$upstream_bytes_sent';access_log /var/log/nginx/web_cluster.log main;# upstream-load_balance-Cluster 这个是负载均衡,下面就是负载均衡的配置upstream web_cluster {server 192.168.40.101:80; # server1 IP:portserver 192.168.40.102:80; # server2 IP:portserver 192.168.40.103:80; # server3 IP:port}server {listen 80; # nginx proxy port -proxy_pass web_cluster; # 添加这个就是反向代理}}##### add to config end ##### 注意:listen port 端⼝号码 - ⽤户访问访问端⼝  server1 IP:port 端⼝号码 - 后端服务的实际端⼝   检查Nginx配置⽂件格式  [root@ha1 nginx]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful  重新加载配置⽂件 [root@ha1 nginx]# nginx -s reload HA2  安装nginx软件 [root@ha2 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo[root@ha2 ~]# yum install -y nginx nginx-mod-stream[root@ha2 ~]# systemctl daemon-reload && systemctl start nginx && systemctl enable nginx && systemctl status nginx [root@ha2 ~]# pstree -ap | grep -v grep | grep -i nginx [root@ha2 ~]# pstree -ap | grep -v grep | grep -i nginx |-nginx,10361 | |-nginx,10362 | `-nginx,10363 [root@ha2 ~]# netstat -nltp | grep -i nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10361/nginx: master tcp6 0 0 :::80 :::* LISTEN 10361/nginx: master Nginx反向代理-负载均衡部署  [root@ha1 ~]# cd /etc/nginx/ [root@ha1 nginx]# mv nginx.conf nginx.conf.bak  修改配置文件 [root@ha1 nginx]# vim nginx.conf# For more information on configuration, see:# * Official English Documentation: http://nginx.org/en/docs/# * Official Russian Documentation: http://nginx.org/ru/docs/user nginx;worker_processes auto;error_log /var/log/nginx/error.log;# [alert] 18037#0: 1024 worker_connections are not enoughpid /run/nginx.pid;# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events {worker_connections 1024; # 最多可以建这么多工作节点}##### add to config start #####stream {log_format main '$remote_addr $upstream_addr - [$time_local] $status$upstream_bytes_sent';access_log /var/log/nginx/web_cluster.log main;# upstream-load_balance-Cluster 这个是负载均衡,下面就是负载均衡的配置upstream web_cluster {server 192.168.40.101:80; # server1 IP:portserver 192.168.40.102:80; # server2 IP:portserver 192.168.40.103:80; # server3 IP:port}server {listen 80; # nginx proxy port -proxy_pass web_cluster; # 添加这个就是反向代理}}检查Nginx配置⽂件格式[root@ha2 nginx]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful重新加载配置⽂件[root@ha2 nginx]# nginx -s reload原文链接:https://blog.51cto.com/u_15397018/6104876
  • [技术干货] 系统管理员排除故障的五种武器【转】
    作为系统管理员,我每天都面临着需要快速解决的问题,用户和管理人员期望事情能够顺利地进行。在我管理的这样的一个大型环境中,几乎不可能从头到尾了解所有的系统和产品,所以我必须使用创造性的技术来找到问题的根源,并(希望可以)提出解决方案。当你不知道从哪里开始时,这五个工具可以帮助你找到用户的 IT 问题的源头。作为系统管理员,我每天都面临着需要快速解决的问题,用户和管理人员期望事情能够顺利地进行。在我管理的这样的一个大型环境中,几乎不可能从头到尾了解所有的系统和产品,所以我必须使用创造性的技术来找到问题的根源,并(希望可以)提出解决方案。这是我 20 多年来的日常经验!每天上班时,我从不知道会发生什么。因此,我有一些快速而简陋的技巧,当一个问题落在我的身上,而我又不知道从哪里开始时,我一般就会采用这些技巧。但等一下!在你直接打开命令行之前,请花一些时间与你的用户交谈。是的,这可能很乏味,但他们可能会有一些好的信息给你。请记住,用户可能没有你那么多的经验,你需要对他们说的东西进行一些解释。试着清楚地了解正在发生什么和应该发生什么,然后用技术语言自己描述故障。请注意,大多数用户并不阅读他们面前的屏幕上的内容;这很可悲,但却是事实。确保你和用户都阅读了所有的文字,以收集尽可能多的信息。一旦你收集到了这些信息,就打开命令行,使用这五个工具。Telnet让我从一个经典开始。​​Telnet​​ 是 SSH 的前身,在过去,它在 Unix 系统上用来连接到远程终端,就像 SSH 一样,但它没有加密。Telnet 在诊断网络连接问题方面有一个非常巧妙和宝贵的技巧:你可以 Telnet 到不是专属于它 TCP 端口(23/TCP)。要做到这一点,可以像平时一样使用 Telnet,但在末尾加上 TCP 端口(例如 ​​telnet localhost 80​​),以连接到一个网络服务器。这可以让你能够检查一个服务器,看看服务是否正在运行,或者防火墙是否阻挡了它。因此,在没有应用程序客户端,甚至没有登录应用程序的情况下,你可以检查 TCP 端口是否有反应。如果你知道怎么做,有时你可以通过在 Telnet 提示符手动输入并获得响应以检查。网络服务器和邮件服务器是你可以这样做的两个例子。Tcpdump​​tcpdump​​ 工具可以让你检查网络上正在传输的数据。大多数网络协议都相当简单,如果你把 ​​tcpdump​​ 和一个像 ​​Wireshark​​ 这样的工具结合起来,你会得到一个简单而好用的方法来浏览你所捕获的流量。在如下的例子中,我在下面的窗口中检查数据包,在上面的窗口连接到 TCP 3260 端口。这张截图显示了在现实世界中使用 Wireshark 查看 iSCSI 协议的情况;在这种情况下,我能够确定我们的 QNAP 网络附加存储的配置方式有问题。find如果你不知道从哪里开始,​​find​​ 命令就是最好的工具。在其最简单的形式中,你可以用它来“寻找”文件。例如,如果我想在所有的目录中进行递归搜索,得到一个 conf 文件的列表,我可以输入:find . -name '*.conf'.但是,​​find​​ 的一个隐藏的宝藏是,你可以用它对它找到的每个项目执行一个命令。例如,如果我想得到每个文件的长列表,我可以输入;find . -name '*.conf' -exec ls -las {}\;一旦你掌握了这种技术,你就可以用各种创造性的方法来寻找、搜索和以特定方式执行程序。strace我是在 Solaris 上认识 ​​strace​​ 这个概念的,在那里它被称为 ​​truss​​。今天,它仍然像多年前一样有用。​​strace​​ 允许你在进程实时运行时检查它在做什么。使用它很简单,只要使用命令 ​​ps -ef​​,找到你感兴趣的进程 ID。用 ​​strace -p <进程 ID>​​ 启动 ​​strace​​,它会开始打印出一大堆东西,一开始看起来像垃圾信息。但如果你仔细观察,你会看到你认识的文字,如 ​​OPEN​​ 和 ​​CLOSE​​ 这样的词和文件名。如果你想弄清楚一个程序为什么不工作,这可以引导你走向正确的方向。grep把最好的留到最后:​​grep​​。这个工具是如此有用和强大,以至于我很难想出一个简洁的方法来描述它。简单地说,它是一个搜索工具,但它的搜索方式使它如此强大。在问题分析中,我通常会用 ​​grep​​ 搜索一堆日志来寻找一些东西。一个叫 ​​zgrep​​ 的配套命令可以对压缩文件做同样的事情。在下面的例子中,我使用 ​​zgrep bancroft /var/log/*​​ 在所有的日志文件中进行 grep,以查看我在系统中的工作情况。我使用 ​​zgrep​​ 是因为该目录中有压缩文件。使用 ​​grep​​ 的另一个好方法是将其他工具的输出通过管道输送到它里面;这样,它就可以作为一种过滤器来使用。在下面的例子中,我列出了 auth 文件,并通过使用 ​​cat auth.log |grep bancroft​​ 来搜索我的登录信息,看看我都做了什么。这也可以写成 ​​grep bancroft auth.log​​,但我这里用管道(​​|​​)来证明这一点。其他需要考虑的工具你可以用这些工具做更多的事情,但我希望这个简单的介绍能给你一个窗口,让你了解如何用它们来解决你遇到的讨厌的问题。另一个值得你注意的工具是 ​​Nmap​​,我没有包括它,因为它是如此全面,需要一整篇文章(或更多)来解释它。最后,我建议学习一些白帽和黑客技术;在试图找出问题的根源时,它们可能非常有益,因为它们可以帮助你收集对决策至关重要的信息。原文链接:https://www.51cto.com/article/700548.html
  • [技术干货] 自动化在DevOps中的力量:简化软件开发和交付【转】
    自动化是DevOps成功的关键因素。它利用专门的软件工具和方法来自动化软件开发和交付过程中的重复性和手动性任务。它旨在减少人为干预,降低错误,并增强团队成员之间的协作和沟通。自动化在DevOps中扮演着重要角色,它提升了DevOps的效能。通过自动化工具和方法,DevOps团队可以实现以下目标:消除手动和重复性任务。简化流程。在整个软件开发生命周期中实现更高的效率。自动化是DevOps成功的关键因素。它利用专门的软件工具和方法来自动化软件开发和交付过程中的重复性和手动性任务。它旨在减少人为干预,降低错误,并增强团队成员之间的协作和沟通。DevOps中的自动化包括规划、编码、构建、测试、发布和监控等软件开发生命周期的各个阶段。通过自动化这些过程,组织可以获得多个好处,如一致性、速度、可伸缩性和改善的协作。下面是自动化在DevOps中带来的好处:一致性:DevOps中的自动化过程是一致且可预测的。与容易出错的手动过程不同,自动化确保任务每次以相同的方式执行。这种一致性提高了可靠性,降低了错误或差异的风险。速度:DevOps的自动化显著加快了软件开发和交付的速度。自动化消除了等待人工干预的需求,使流程能够立即开始。此外,自动化的流程比手动的流程执行速度要快得多。代码集成、测试和部署等任务几乎可以瞬间完成,使组织能够快速高效地发布软件更新和功能。可伸缩性:自动化对于扩展DevOps流程至关重要。随着组织的增长和管理多个应用程序和环境,手动管理变得不切实际和低效。自动化工具通过自动化手动处理耗时且容易出错的任务,实现无缝扩展。通过自动化,组织可以在业务扩展的同时保持相同的速度和质量。改善的协作:自动化促进团队成员之间更好的协作和沟通。通过自动化重复和常规任务,团队成员可以将重心放在更有价值的工作上,如创新和解决问题。自动化工具还提供了可见性和透明度,使团队成员能够轻松跟踪任务进展、识别瓶颈并有效协作。需要自动化的DevOps流程:尽管自动化可以应用于DevOps的各个流程,但优先考虑为组织带来最大价值的流程非常重要。以下是可以在DevOps中自动化的一些关键流程:规划:规划阶段为软件开发奠定了基础。自动化规划流程(如收集需求、创建发布计划和建立安全策略)可以帮助简化开发的初期阶段。可以使用像Jira、GitHub和Asana这样的工具自动化任务跟踪、问题管理和项目规划。编码:编码阶段的自动化涉及使用源代码仓库(如Git和Subversion)管理代码版本并促进开发人员之间的协作。可以使用自动化代码审查工具确保代码质量和符合编码标准。构建:构建阶段的自动化侧重于将代码编译为可执行的构建结果,并运行自动化测试来验证代码的功能。可以使用像GitLab和Jenkins这样的持续集成工具自动化构建过程,并在对代码仓库进行更改时自动触发测试。测试:自动化测试是DevOps自动化的一个关键方面。它涉及运行各种类型的测试(包括单元测试、集成测试和性能测试),以验证软件的功能和质量。可以将Selenium和JUnit等测试框架集成到DevOps流水线中,自动执行测试并生成测试报告。发布和部署:自动化发布和部署过程可以确保高效且无错误的软件发布。可以使用像Ansible和Chef这样的发布自动化工具将软件打包和部署到生产环境中。可以建立自动化的部署流水线来处理整个发布过程,包括配置管理、环境配置和部署后验证。监控和运维:监控和运维方面的自动化侧重于持续监控生产环境中软件的性能和健康状况。像Sumo Logic这样的监控工具提供实时洞察和警报功能,使组织能够主动识别和解决可能出现的任何问题。还可以实施自动化的事故响应和修复工作流程,以减少停机时间并确保快速解决问题。综合DevOps工具链数据的方法:随着组织采用各种工具和技术来实施DevOps,管理和聚合整个工具链中的数据变得至关重要。综合的DevOps工具链数据方法允许组织全面了解其软件开发和交付过程,识别瓶颈并做出数据驱动的决策。像Sumo Logic这样的工具提供了一个集中的平台,与Jira、GitHub、Jenkins等领先的DevOps工具集成。这种集成允许组织实时收集和分析来自不同来源的数据,使其能够监控性能、跟踪关键指标并优化其DevOps工作流程。结论:自动化是DevOps领域的一个重要变革者。通过自动化重复和手动任务,组织可以在软件开发和交付过程中实现更高的效率、速度和可靠性。从规划到监控,自动化可以应用于DevOps流水线的各个阶段,使团队能够有效协作、扩展运营并以加快的速度交付高质量的软件。为了充分发挥DevOps中自动化的威力,组织应采用统一的工具链数据方法,并将安全作为开发过程的一部分。通过正确的工具和方法,组织可以释放DevOps的潜力,并在当今竞争激烈的数字化领域中保持领先地位。拥抱自动化,简化你的DevOps工作流程,体验它对软件开发和交付过程的变革影响。保持敏捷,保持竞争力,拥抱DevOps自动化的力量。原文链接:https://www.51cto.com/article/762209.html
  • [技术干货] DevOps理念:开发与运维的融合【转】
    在现代软件开发领域,DevOps 不仅仅是一个流行的词汇,更是一种文化、一种哲学和一种方法论。DevOps 的核心理念是通过开发和运维之间的紧密合作,实现快速交付、高质量和持续创新。本文将深入探讨 DevOps 文化的重要性、原则以及如何在团队中实现开发与运维的融合。在现代软件开发领域,DevOps 不仅仅是一个流行的词汇,更是一种文化、一种哲学和一种方法论。DevOps 的核心理念是通过开发和运维之间的紧密合作,实现快速交付、高质量和持续创新。本文将深入探讨 DevOps 文化的重要性、原则以及如何在团队中实现开发与运维的融合。什么是 DevOps?DevOps 是 Development(开发)和 Operations(运维)的合并,是一种促使开发和运维团队紧密合作的文化和实践。它旨在消除传统开发和运维之间的壁垒,加强协作,实现软件交付的持续性和质量。DevOps 的核心原则1. 自动化DevOps 鼓励使用自动化工具来执行常见的任务,包括构建、测试、部署和监控。自动化可以降低人工错误,加快交付速度,并提高一致性。2. 持续集成和持续交付通过持续集成(CI)和持续交付(CD)实践,开发团队可以频繁地将代码集成到共享的代码库中,并自动化地将变更部署到生产环境中,从而快速地交付新功能和修复。3. 跨功能团队协作DevOps 鼓励开发、测试和运维团队之间的紧密协作。不再是各自为战,而是共同合作,分享知识和责任,以实现共同的目标。4. 反馈循环通过实时监控和反馈,DevOps 团队可以快速发现和解决问题。这有助于持续改进,提高系统的稳定性和性能。5. 基于数据的决策DevOps 鼓励使用数据来指导决策。通过收集和分析性能指标和用户反馈,团队可以做出更明智的决策,优化流程。DevOps 文化的重要性1. 加速交付速度DevOps 的自动化和持续集成/持续交付实践能够显著减少开发到生产的交付时间。这有助于及早地将新功能、改进和修复带到用户手中。2. 提高质量通过自动化测试和持续集成,DevOps 可以确保每次代码更改都经过严格的测试。这有助于提高软件的稳定性和可靠性。3. 增强可靠性DevOps 强调持续监控和反馈,使团队能够更早地发现问题并及时解决。这有助于提高系统的可靠性,并减少意外的中断。4. 提升团队协作DevOps 的跨功能团队协作能够消除团队之间的隔阂,促使开发、测试和运维团队共同合作。这有助于创造一个更有创造力和积极性的工作环境。5. 促进创新通过快速交付和持续改进,DevOps 鼓励团队不断尝试新的想法和解决方案。这有助于推动创新和业务增长。实现 DevOps 文化的步骤1. 打破隔阂消除开发和运维之间的隔阂,鼓励紧密合作和信息共享。可以通过共同的工作流程、工具和沟通渠道来实现。2. 自动化流程引入自动化工具来支持构建、测试、部署和监控。自动化能够提高效率,减少手动操作的风险。3. 持续改进实施持续反馈和持续改进的实践,通过监控和数据分析来发现问题,并及时采取措施进行改进。4. 促进学习与培训提供培训和知识共享机会,让团队成员了解 DevOps 的原则和最佳实践,以及如何运用它们来提升团队的能力。5. 文化变革DevOps 并不仅仅是工具和流程,更是一种文化。鼓励团队成员拥抱变革,从而实现开发和运维的真正融合。总结DevOps 文化代表了一种开发和运维融合的理念,通过自动化、持续集成、持续交付以及团队协作,构建出更高效、质量更高的软件交付流程。通过打破传统的开发与运维之间的隔阂,促使团队紧密合作、持续创新和快速交付,DevOps 成为现代软件开发的关键要素之一。在一个竞争激烈、迅速变化的市场环境中,DevOps 提供了一种有效的方法来应对不断变化的需求和挑战。通过自动化流程,快速交付新功能和改进,提高质量和可靠性,团队可以更灵活地适应市场的需求,提升用户体验,赢得客户的信任。然而,实施 DevOps 文化并不是一蹴而就的过程。它需要团队成员的共同努力、领导者的支持,以及不断的学习和改进。逐步地引入自动化、持续集成、持续交付等实践,培养团队协作和持续改进的习惯,可以帮助组织逐步转变为一个具有高效交付能力的 DevOps 文化。在 DevOps 文化的指导下,开发和运维团队不再是独立的个体,而是共同合作的伙伴。通过共享知识、资源和责任,他们共同推动软件的生命周期,不断提升交付流程的效率和质量。在这种协作和创新的环境中,团队可以更好地应对挑战,迎接机遇,实现持续的成功和成长。原文链接 https://www.51cto.com/article/764959.html
  • [技术干货] 云原生架构,DevOps 介绍【转】
    云原生架构(Cloud-Native Architecture)是一种基于云计算的应用程序架构和开发方法论,旨在充分发挥云计算平台的优势,提高应用程序的可伸缩性、弹性和可靠性。云原生架构(Cloud-Native Architecture)是一种基于云计算的应用程序架构和开发方法论,旨在充分发挥云计算平台的优势,提高应用程序的可伸缩性、弹性和可靠性。它强调将应用程序设计为微服务、采用容器化部署、自动化管理和持续交付,以实现快速迭代、高效部署和可靠运行。云原生架构的关键特点包括:微服务架构:将应用程序拆分为多个独立的、自治的微服务,每个微服务负责特定的业务功能,并可以独立开发、部署和扩展。微服务之间通过轻量级的通信机制进行交互,例如RESTful API或消息队列。2. 容器化部署:使用容器技术(如Docker)将每个微服务及其依赖项打包成独立的可移植单元。容器提供了环境隔离、一致性和可移植性,使得应用程序可以在不同的环境中轻松部署和运行。3. 自动化管理:利用自动化工具和平台来管理应用程序的部署、配置、扩缩容、监控和治理等任务。自动化减少了人为操作的错误和复杂性,提高了开发和运维的效率。4. 弹性和可伸缩性:云原生架构倡导根据需求动态调整应用程序的资源,实现弹性和可伸缩性。通过自动化的资源管理和负载均衡,应用程序可以根据实际负载进行水平扩展或收缩,以满足用户需求并提供良好的性能。5. 持续交付:采用持续集成和持续部署(CI/CD)的工作流程,实现快速、可靠的应用程序交付。开发团队可以频繁地进行代码集成、构建、测试和部署,以快速响应需求变化,并确保软件质量和稳定性。DevOps(Development and Operations)是一种软件开发和运维的文化和实践方法,旨在通过加强开发团队和运维团队之间的协作和沟通,实现快速交付高质量的软件。DevOps强调自动化、持续集成、持续交付和持续部署等实践,以加速软件开发周期、降低风险和提高团队效率。DevOps的关键原则包括:自动化:DevOps倡导通过自动化工具和流程来实现软件开发、测试、部署和运维的自动化。自动化减少了人为错误,提高了效率和一致性。2. 持续集成(Continuous Integration):开发团队频繁地将代码集成到共享存储库中,并通过自动化构建和测试流程进行验证。持续集成确保了代码的质量和稳定性,并提早发现和解决问题。3. 持续交付(Continuous Delivery):持续交付是指在持续集成的基础上,通过自动化的构建、测试和部署流程,将可部署的软件交付给用户。这样可以快速响应用户需求,并降低发布新功能和修复错误的时间。4. 持续部署(Continuous Deployment):持续部署是指将通过持续交付生成的可部署软件自动发布到生产环境中,实现快速的软件发布。持续部署能够快速迭代和交付新功能,提高用户满意度和市场竞争力。5. 跨职能团队合作:DevOps鼓励开发团队和运维团队之间的紧密合作和沟通。通过打破传统的组织和职能隔离,促进团队之间的合作,可以更快地解决问题、提供更好的用户体验。6. 基础设施即代码(Infrastructure as Code):基础设施即代码是指使用代码来定义和管理基础设施资源,例如服务器、网络和存储等。通过基础设施即代码,可以实现基础设施的版本控制、自动化部署和可重复性,提高了部署的速度和可靠性。DevOps的应用可以带来以下优势:● 快速交付:通过自动化和持续集成、持续交付的实践,能够快速交付高质量的软件,缩短上线时间,提高产品迭代速度。● 高质量:通过自动化测试和持续集成,能够更早地发现和解决问题,提高软件的质量和稳定性。● 高效协作:通过跨职能团队合作和沟通,打破组织和职能的隔离,加快问题解决和决策过程,提高团队效率。● 可靠性和稳定性:通过自动化部署和基础设施即代码,减少人为错误和手动操作,提高系统的可靠性和可维护性,降低故障风险,提高系统的稳定性。● 灵活性和可扩展性:通过容器化和弹性伸缩的技术,能够快速调整应用程序的资源,根据实际需求进行扩展或缩减,以适应不断变化的业务需求。● 可追溯性和可恢复性:通过版本控制和日志记录,能够追踪系统的变更和操作历史,便于故障排查和回滚操作,提高系统的可追溯性和可恢复性。● 成本效益:通过自动化和资源优化,能够减少人力成本和资源浪费,提高IT资源的利用率,降低运维和部署的成本。总的来说,DevOps作为一种文化和实践方法,通过强调自动化、协作和持续交付,可以提高软件开发和运维的效率和质量,促进团队之间的协作和沟通,实现快速、稳定和可靠的软件交付,以满足不断变化的业务需求。原文链接:https://www.51cto.com/article/765327.html
总条数:18 到第
上滑加载中