关于服务:什么是-Service-Ticket-的-Service-Level-Agreement

服务工单(Ticket)的服务级别协定(Service Level Agreement,SLA)是一个重要的概念,特地是在提供技术支持和客户服务的畛域中。服务工单是组织内或与客户之间的通信记录,用于跟踪问题、申请或工作的解决。SLA是一种协定或承诺,其中规定了一组指标和参数,以确保服务工单失去适时、高质量的解决。本文将具体介绍什么是服务工单的SLA,以及通过理论示例阐明SLA如何利用于技术支持和客户服务环境中。 什么是服务级别协定(SLA)?服务级别协定(SLA)是一种合同性协定,通常以书面形式存在,它规定了提供方(通常是服务提供商或反对团队)与接管方(通常是客户)之间的服务质量和性能规范。SLA的指标是确保服务提供商在肯定的工夫内提供肯定品质的服务,以满足客户的冀望和需要。服务工单的SLA通常包含以下重要元素: 响应工夫:即服务提供商承诺在接管服务工单后的肯定工夫内做出回应。这能够是一个固定的工夫,例如30分钟,也能够是依据问题的优先级而变动的工夫。解决工夫:这是指服务提供商承诺在接管服务工单后的肯定工夫内解决问题或实现工作。相似于响应工夫,解决工夫也能够依据问题的优先级而变动。可用性:如果服务提供商是负责保护零碎或基础设施的,SLA可能包含对这些零碎或设施的可用性要求。例如,一个SLA可能规定某个在线服务必须每月至多可用99.9%的工夫。服务质量:SLA通常定义了服务的质量标准,包含性能、可靠性和可用性。这些规范可能依据不同的服务类型和业务需要而有所不同。优先级:SLA通常依据服务工单的优先级来确定响应和解决工夫的要求。紧急的问题可能须要更短的响应和解决工夫,而较低优先级的问题可能有更长的工夫容忍度。处罚和处分:SLA可能包含对服务提供商违反协定的处罚措施,例如升高费用或提供额定的服务。同时,它也能够包含对达到或超过协定要求的处分,例如提供额定的反对或折扣。SLA的重要性服务级别协定在技术支持和客户服务畛域中具备极大的重要性,因为它们有助于确保以下方面: 客户满意度:通过明确的SLA,客户能够理解何时能够冀望问题失去解决,这有助于进步客户满意度。服务可靠性:SLA迫使服务提供商放弃高水平的服务可用性和性能,有助于防止零碎中断和服务故障。资源布局:服务提供商能够依据SLA中的要求来布局和分配资源,以确保满足承诺的工夫和质量标准。业务单干:在商业单干关系中,SLA能够作为一种合同来明确各方的责任和任务,缩小潜在的争议和误会。绩效评估:SLA提供了一种度量服务提供商绩效的办法,能够用于改良流程和进步服务质量。当初,让咱们通过一个理论的示例来具体阐明服务工单的SLA如何工作。 示例:技术支持服务工单的SLA假如你是一家技术支持公司的高级反对工程师,你的团队负责为企业客户解决各种技术问题。你的公司与客户签订了一个服务级别协定(SLA),以确保提供高质量的反对服务。以下是该SLA的具体内容: 1. 响应工夫优先级1问题:对于最紧急的问题,咱们承诺在接管工单后的15分钟内做出响应。优先级2问题:对于高优先级问题,咱们承诺在接管工单后的1小时内做出响应。优先级3问题:对于一般优先级问题,咱们承诺在接管工单后的4小时内做出响应。2. 解决工夫优先级1问题:对于最紧急的问题,咱们承诺在接管工单后的2小时内解决问题。优先级2问题:对于高优先级问题,咱们承诺在接管工单后的8小时内解决问题。优先级3问题:对于一般优先级问题,咱们承诺在接管工单后的24小时内解决问题。3. 可用性咱们保障咱们的在线反对平台每月至多可用99.9%的工夫。如果可用性低于此程度,咱们将提供额定的反对或处分。 4. 服务质量咱们承诺在解决问题时提供高质量的反对,包含具体的解决方案和跟进。咱们将监控咱们的服务性能,以确保疾速辨认和解决任何性能问题。5. 优先级客户能够为每个服务工单调配优先级,以帮忙咱们依据SLA要求进行解决。优先级将依据问题的紧急性、影响水平和客户需要来确定。6. 处罚和处分如果咱们未能满足SLA中的响应或解决工夫要求,咱们将提供额定的反对,并依据状况提供局部退款或折扣。如果咱们超过SLA要求,咱们将提供额定的处分,例如收费培训或额定的反对工夫。以上是一个典型的技术支持服务工单的SLA示例。客户和反对团队能够依据具体的业务需要和客户冀望来定制SLA。通过明确定义响应和解决工夫、可用性、服务质量和优先级,SLA有助于确保客户取得高质量的技术支持,同时也激励反对团队不断改进他们的服务流程和绩效。 总结服务级别协定(SLA)对于确保提供高质量的反对和服务至关重要。它们定义了服务工单的响应工夫、解决工夫、可用性、服务质量和优先级,以满足客户的需要和冀望。通过施行SLA,服务提供商能够进步客户满意度,确保服务的可靠性,布局资源,缩小潜在的争议,并继续改良服务质量。在技术支持和客户服务环境中,SLA是一种不可或缺的工具,有助于建设巩固的客户关系并实现业务指标。

September 24, 2023 · 1 min · jiezi

关于服务:融云-CallPlus-SDK-上线1V1-音视频远程服务类应用的实现利器

点击图片报名,9 月 21 日融云直播课 近期,融云新一代音视频通话场景化 SDK CallPlus 将正式上线! 融云 CallPlus 残缺封装了拨打、振铃、接听、挂断等整套呼叫流程,反对一对一及群组多人音视频通话。 在性能上,融云 CallPlus 以独立后端保障状态统一性和业务扩展性,上新了视频预览,美颜设置,音频通话、视频通话互转等丰盛性能。 符合海内用户的交互偏好,融云 CallPlus 独家提供通话记录治理能力,包含查问用户通话记录列表、删除通话记录等性能,贴近 WhatsApp、Telegram 等国内产品的应用体验。 在集成上,融云 CallPlus 采纳平铺式接口设计,且提供 Quick Demo 源码供开发者集成参考,开发者只需一天即可集成一款功能齐全、体验丝滑的音视频通话利用。 [更多细节,尽在 9 月 21 日融云直播课点此报名吧~](https://www.huodongxing.com/event/2717788905323?qd=weixin) 性能残缺融云 CallPlus SDK 将呼叫场景业务流程进行了残缺封装,且基于弱小的 RTC 实时音视频能力构建,可助力开发者疾速实现高清、低提早的一对一、多对多实时音视频通话能力。 并且,SDK 在性能完整性和体验细腻度上优于行业其余产品。 独立后端服务融云针对音视频呼叫场景独自设计呼叫后端服务 Call Server,将通话状态及相干业务的解决放在服务端,客户端只须要依据上行信令进行相应状态的解决即可。 Call Server 负责整个呼叫流程的治理,简化了客户端的实现复杂度,保障了信息的一致性,让业务的扩大变得更加熟能生巧。同时,还将带来以下劣势: 独立的信令下发通道不与 IM 音讯抢占通道,呼叫提早更低,呼叫成功率更高。 欠缺的通话状态治理用户通话状态(通话中、呼叫中、闲暇等)实时可查,用户异样退出等可实现断线重连。 精准计时及多种计划Call Server 对立下发通话的开始和完结工夫,确保各端计时统一;反对按收到首帧计时和退出 RTC 房间胜利后计时两种计划,满足不同客户需要。 SDK 性能上新通话前视频预览及美颜设置融云 CallPlus 反对通话前视频预览及美颜设置,SDK 曾经内置了根底美颜能力,并提供高级美颜插件接口供有须要的开发者抉择。 顺畅的音视频通话互转反对用户在通话过程中,由语音通话到视频通话的降级,及由视频通话到语音通话的降级解决,无需挂断从新发动。 这一场景波及简单的交互解决:主叫和被叫进行转换通话模式的协商,对端应答后,实现音频、视频通话的互相转换。融云 CallPlus 封装了所有操作和解决逻辑,让这个场景下的用户应用更加便捷。 更灵便的多人通话场景反对用户被动退出多人通话,且不限度通话用户是否在同一个群组内。 这样,临时未参加群通话的用户,能够抉择在完结前的任意工夫退出通话,解决办公场景中的常见状况——用户随时退出起初无奈接听的群组会议,或在群组会议过程中新增参加人。 独家提供通话记录治理能力在绝大部分国内 App 中,音视频通话完结后,会将通话记录以一条音讯的模式下发到会话内。 ...

August 29, 2023 · 1 min · jiezi

关于服务:更专业的出海服务商融云荣膺-GTC2022-鲸鸣奖优秀出海服务商

明天,为期 2 天的白鲸出海“GTC2022 寰球流量大会”在深圳揭幕,融云受邀参会。关注【融云寰球互联网通信云】理解更多 由出海企业代表、出海媒体及协会、业内权威机构和政府相干部门独特参加评比的“GTC2022 鲸鸣奖”正式颁发,融云荣膺“优良出海服务商”。在大会的“音视频社交专场”论坛,融云出海行业专家冯思带来《实时互动再进阶,摸索泛娱乐出海新引擎》主题演讲,分享融云出海多年的实践经验和成绩积攒。 继续精进 更优良的寰球通信网作为最早随中国出海企业将服务触角伸向寰球的通信云服务商之一,为了给寰球用户提供敌对的应用体验,融云自 2015 年起就开始自建寰球网络,并是过后惟一上线了海内数据中心的通信服务商。 尔后,融云将通信网络覆盖至寰球 233 个国家和地区,成为出海开发者首选的通信搭档,反对寰球 30 万+ 款 App 顺畅、稳固通信。 仅在出海服务方面,融云日音讯峰值达 440 亿+,日均音讯量 92 亿+,日均沉闷数 4500 万+,SDK 触达用户数 44 亿+。在继续服务出海客户的过程中,融云一直对寰球通信网进行迭代优化,实现了用户可能就近接入、通信品质稳固、反对动静门路切换的一体化通信网建设,实现了平安、牢靠的寰球互联互通。 随着中国互联网出海浪潮迭起,出海开发者对高质量的寰球通信服务提出更高要求。同时,融云在各地区的本地化建设逐步深刻,驱动寰球通信服务进一步降级,全新一代寰球通信网 SD-CAN V4 正式上线! 网络优化体现☑ 针对 TCP 和 UDP 进行减速,连贯时长升高了 30%。☑ 自研 DoH 调度零碎,极大晋升解析速度,同时防止海内网络的歹意攻打劫持。☑ 全线反对最新的 HTTP/3 协定,将基础设施受限地区的连贯成果晋升 40%。 体验优化体现☑ 寰球支流手机适配,设施解体率低于 0.02%。☑ 高清图片 WebP 压缩算法,图片清晰度优于国内支流利用。☑ 小视频分片压缩并行上传,分段缓存,速度晋升了 90%。☑ 呼叫和全局双向申请对 Gzip 和 Brotli 算法进行了优化,传输体积降落了 85%。☑ IM 上行告诉触达优化,速度为官网 iOS/Android Push 通道的 10 倍。 深耕多年 更业余的出海服务商在稳固强壮的通信网络之外,融云还在多年实际中一直积淀相干劣势,以体系化能力为开发者提供更业余的出海服务。 ...

March 1, 2023 · 1 min · jiezi

关于服务:服务网格-ASM-2022年12月产品动态

February 7, 2023 · 0 min · jiezi

关于服务:亚马逊云科技-2022-年-3-月新服务新功能强势来袭

从计算、存储和数据库等基础设施技术,到机器学习、人工智能、数据湖和剖析以及物联网等新兴技术,亚马逊云科技为客户提供多样的服务及性能。借助亚马逊云科技,您能够在品种繁多的前沿技术中抉择适宜您工作负载的服务和性能来进行构建及翻新。 在过来的三月份,由西云数据经营的亚马逊云科技中国(宁夏)区域落地了 40 个新性能或新服务。咱们将基于客户需要来一直的放慢翻新的步调,晋升客户的应用体验。 重磅服务Amazon EC2 Spot Placement Score,可能依据客户 Spot 容量需要来举荐适合的可用区。Amazon RDS 以及 Amazon Aurora 反对 T4g 数据库实例。Amazon Lambda 反对 Amazon MSK 及自建的 ApacheKafka 作为事件源。Amazon S3 反对应用客户定义的校验和算法以放慢申请完整性检查的速度。Amazon Organizations 现容许用户通过控制台和 API/SDK 集中敞开账户。计算Amazon EC2 Spot Placement Score2022 年 3 月 17 日    Amazon EC2 Spot Placement Score 能够帮忙您找到 Spot 工作负载的适宜可用区和实例类型抉择。Spot 实例的可用性因实例类型、工夫和可用区而有所不同。该性能能够依据您的 Spot 容量需要举荐一个可用区。您还能够测试不同的实例类型组合,从而找到一个适宜您的工作负载的实例类型组合,取得您须要的容量。 Amazon EC2 Auto Scaling 推出实例生命周期状态2022 年 3 月 28 日    借助这个新性能,您可能在实例从一个生命周期状态转换到另一个生命周期状态时轻松触发实例上的操作。Auto Scaling 组中的实例在各种生命周期状态中转换,从其启动并投入服务到从服务移除并终止。通过轮询 IMDS,您能够设置实例上的应用程序,以轻松确定其生命周期状态,而无需设置 Amazon CloudWatch Events 或其余服务。 剖析EMR Notebooks 现已降级到 JupyterLab v3.1.42022 年 3 月 1 日 ...

April 18, 2022 · 6 min · jiezi

关于服务:把程序做成系统服务

写程序,难免会遇到须要做成零碎服务的需要。Windows 下写零碎服务须要实现一些特定的接口,做起来有肯定难度,所以不少程序采纳了 近似的备选计划 —— 做成带零碎任务栏图标的桌面利用。然而,服务之所以是服务,就在于他有一个十分重要的特点:能够开机自启动,而且不须要用户登录。要不然每次重启还得人工去登录,是件如许辛苦的事件。Windows 当然是能够设置主动登录的,但如果是托管服务器,你真释怀主动登录吗? 而 Linux 上面仿佛就要不便得多,大略不须要 GUI 继续运行的程序都能够做成服务。 1. 在 Windows 中做服务先说 Windows。如果你还在用 Windows XP,那咱们就此别过 …… 1.1. Windows Service Wrapper[Windows Service Wrapper] 是全称。其简称 WinSW 的知名度可能更高一些。 WinSW 基于 .NET Framework 4.6.1 和 .NET 5 实现,所以至多须要 Windows 7 SP1 / Windows Server 2008 R2 SP1 才能够应用。它能够把任意 Windows 程序封装成 Windows 服务,你所须要做的,只是写个配置文件,而后用 WinSW 注册一个 Windows 服务即可。WinSW 下载下来是个独立的可执行文件,应用前须要写一个与可执行文件名同名但扩展名是 .xml 的配置文件置于同一目录下。 举例来说,Nginx 自身并没有提供注册成 Windows 服务的能力,如果须要注册成 Windows 服务,就能够用 WinSW 来封装一下。把下载的 WinSW 可执行文件改名为 winsw.exe(轻易改成什么名字都行,配置文件名按雷同的名称创立即可),放在 nginx 的主目录上面,创立配置文件之后的目录构造大略是这样: ...

November 2, 2021 · 2 min · jiezi

关于服务:得物技术浅谈服务发布时网络抖动

抛出问题服务部署后一段时间内常常会遇见接口调用超时,这种问题在流量稍大的时候很容易遇见,举例已经做过的一个服务,整个服务只对外提供一个接口,性能属于密集计算型,会通过一系列的简单解决,实例启动时借助Redis实现了数据的全量缓存,运行中很少有底层库的读写,且减少了Gauva本地缓存,所以服务处理速度很快,响应工夫稳固在1-3ms,2个异地集群8台2核4G机器,平时的QPS维持在1300左右。看似完满的服务却在中期呈现一个很头疼的问题,每次迭代线上部署上游总会呈现“抖动”的问题,响应工夫会飙升到秒级别,而这种非主链路的服务在响应工夫上有严格的要求,个别不会超过50~100ms。 解决历程这里简略说下解决问题的历程,不再具体开展具体步骤。 1.尝试第一步 起初猜测是服务启动后的一段时间内会有一些初始化和缓存的操作,或者服务还有序列化器须要建设申请和响应的序列化模型,这些都会让申请变慢,所以尝试在流量切入之前做预热。 2.尝试第二步 通过以上指标能够发现服务在部署的时候CPU飙升,内存还算失常,沉闷线程数飙高,不难看出,CPU飙升是因,Http线程数飙升是果,此时能够先疏忽CPU在忙什么,通过加机器配置排查问题。 3.尝试第三步走到这里就阐明后面尝试都以失败告终,无脉络的时候又认真翻看下监控指标,发现还有一个异样指标,如下图: JVM的即时编译器工夫达到40s+,从而导致CPU飙高,线程数减少,最初呈现接口超时也就不难理解了。找到起因接下来就三部曲剖析下,是什么,为什么,怎么做? 即时编译器是什么1. 概述编程语言分为高级语言和低级语言,机器语言和汇编语言属于低级语言,人类编写的个别是高级语言,列如C,C++,Java。机器语言是最底层的语言,可能被计算机间接执行,汇编语言通过汇编器翻译成机器执行而后执行,高级语言的执行类型有三种,编译执行、解释执行和编译解释混合模式,Java起初被定义为解释执行,起初支流的虚拟机都蕴含了即时编译器,所以Java是属于编译和解释混合模式,首先通过javac将源码编译成.class字节码文件,而后通过java解释器解释执行或者通过即时编译器(下文中简称JIT)预编译成机器码期待执行。 JIT并不是JVM必须的局部,JVM标准中也没有规定JIT必须存在,更没有规定如何实现,它存在的次要意义在于进步程序的执行性能,依据“二八定律”,百分之二十的代码占用百分之八十的资源,咱们称这些百分之二十的代码为“热点代码”(Hot Spot Code),针对热门代码咱们用JIT编译成与本地平台相干的机器码,并进行各层次的深度优化,下次应用时不再进行编译间接取编译后的机器码执行。而针对非“热点代码”应用绝对耗时的解释器执行,将咱们的代码解释成机器能够辨认的二进制代码,解释一句执行一句。 2. 解释器和编译器比照解释器:边解释边执行,省去编译的工夫,不会生成两头文件,不必把全副代码都编译,能够及时执行。编译器:多出编译的工夫,并且编译后的代码大小会成倍的收缩,但编译后的可执行文件运行更快且能复用。咱们所说的JIT比解释器快,仅限于“热点代码”被编译之后的执行比解释器解释执行快,如果只是单次执行的代码,JIT是要比解释器慢的。依据两者的劣势,对于服务要求疾速重启或者内存资源限度较大的解释器能够发挥优势,程序运行后,编译器将逐步发挥作用,把越来越多的“热门代码”编译成本地代码来提高效率。此外,解释器还能够作为编译器进行优化的一个“逃生门”,当激进优化的假如不成立时能够通过逆优化退回到解释器状态继续执行,两者可能相互协作,舍短取长。 即时编译器的类型在HotSpot虚拟机中,内置了两个JIT:Client Complier和Server Complier,简称C1、C2编译器。后面提到JVM是属于解释和编译混合的模式,程序应用哪个编译器取决于虚拟机的运行模式,虚构机会依据本身的版本与宿主机的硬件性能主动抉择,用户也能够应用“-client”或者“-server”参数指定应用哪个编译器。 C1编译器:是一个简略疾速的编译器,次要的关注点在于局部性的优化,采纳的优化伎俩绝对简略,因而编译工夫较短,实用于执行工夫较短或对启动性能有要求的程序,比方GUI利用。C2编译器:是为长期运行的服务器端应用程序做性能调优的编译器,采纳的优化伎俩绝对简单,因而编译工夫较长,但同时生成代码的执行效率较高,实用于执行工夫较长或对峰值性能有要求的程序。 Java7引入了分层编译,这种形式综合了C1的启动性能劣势和C2的峰值性能劣势。分层编译将JVM的执行状态分为了5个档次:第0层:程序解释执行,默认开启性能监控性能(Profiling),如果不开启,可触发第1层编译。第1层:可称为C1编译,将字节码编译为本地代码,进行简略、牢靠的优化,不开启Profiling。第2层:也称为C1编译,开启Profiling,仅执行带办法调用次数和循环回边执行次数Profiling的C1编译。第3层:也称为C1编译,执行所有带Profiling的C1编译。第4层:可称为C2编译,也是将字节码编译为本地代码,然而会启用一些编译耗时较长的优化,甚至会依据性能监控信息进行一些不牢靠的激进优化。 在Java8中默认开启分层编译(-XX:+TieredCompilation),-client和-server的设置曾经是有效的了。如果只想用C1,能够在关上分层编译的同时应用参数“-XX:TieredStopAtLevel=1”。如果只想用C2,应用参数“-XX:-TieredCompilation”敞开分层编译即可。如果只想有解释器的模式,能够应用“-Xint”,这时JIT齐全不染指工作。如果只想有JIT的编译模式,能够应用“-Xcomp”,此时解释器作为编译器的“逃生门”。 通过java -version命令行能够间接查看到以后零碎应用的编译模式。如下图所示: 4.热点探测即时编译器判断某段代码是不是“热点代码”的行为叫做热点探测,分为基于采样的热点探测和基于计数器的热点探测。 基于采样的热点探测:虚拟机周期性的对各个线程的栈顶进行查看,如果发现某个办法经常出现那这个办法就是“热点代码”,这种热点探测实现简略、高效、容易获取办法之间的调用关系,但很难准确的确认办法的热度,而且容易受到线程阻塞或其余外因的烦扰。 基于计数器的热点探测:虚拟机为每个办法或代码块建设计数器,统计代码的执行次数,如果超过肯定的阈值就认为是“热点代码”,这种形式实现麻烦,不能间接获取办法间的调用关系,须要为每个办法保护计数器,然而能准确统计热度。 HotSpot虚拟机默认是基于计数器的热点探测,因为“热点代码”分为两类:被屡次调用的办法和被屡次执行的循环体,所以该热点探测计数器又分为办法调用计数器和回边计数器。这里须要留神,两者最终编译的对象都是残缺的办法,对于后者,只管触发编译的动作是循环体,但编译器仍然会编译整个办法,这种编译形式因为编译产生在办法的执行的过程中,因而称之为栈上替换(On Stack Replacement, 简称OSR编译)。 办法调用计数器:用于统计办法被调用的次数,在C1模式下默认阈值是1500次,在C2模式在是10000次,可通过参数-XX: CompileThreshold来设定。而在分层编译的状况下,-XX: CompileThreshold指定的阈值将生效,此时将会依据以后待编译的办法数以及编译线程数来动静调整,当办法计数器和回边计数器之和超过办法计数器阈值时,就会触发JIT编译器,触发时执行引擎并不会同步期待编译的实现,而是持续依照解释器执行字节码,编译申请实现之后零碎会把办法的调用入口改成最新的地址,下一次调用时间接应用编译后的机器码。 如果不做工作的设置,办法调用计数器统计的并不是相对次数,而是一个绝对的执行频率,即一段时间内被调用的次数,当超过工夫限度调用次数依然未达到阈值,那么该办法的调用次数就会减半,此行为称之为办法调用计数器热度的衰减,这段时间称为此办法的统计半衰周期,能够应用虚拟机参数-XX:-UseCounterDecay敞开热度衰减,也能够应用参数-XX:CounterHalfLifeTime设置半衰周期的工夫,须要留神进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的。 回边计数器:用于统计一个办法中循环体代码执行的次数,在字节码中遇到管制流向后跳转的指令称为回边。与办法计数器不同,回边计数器没有计数热度衰减的过程,统计的是办法循环执行的相对次数。当计数器溢出时会把办法计数器的值也调整到溢出状态,这样下次再进入该办法时就会执行编译过程。在不开启分层编译的状况下,C1默认为13995,C2默认为10700,HotSpot提供了-XX:BackEdgeThreshold来设置回边计数器的阈值,然而以后虚拟机实际上应用-XX: OnStackReplacePercentage来间接调整。 Client模式下:阈值=办法调用计数器阈值(CompileThreshold)*OSR比率(OnStackReplacePercentage)/ 100。默认值CompileThreshold为1500,OnStackReplacePercentage为933,最终回边计数器阈值为13995。 Server模式下:阈值=办法调用计数器阈值(CompileThreshold)*(OSR比率(OnStackReplacePercentage)-解释器监控比率(InterpreterProfilePercentage))/ 100。默认值CompileThreshold为10000,OnStackReplacePercentage为140,InterpreterProfilePercentage为33,最终回边计数器阈值为10700. 而在分层编译的状况下,-XX: OnStackReplacePercentage指定的阈值同样会生效,此时将依据以后待编译的办法数以及编译线程数来动静调整。 即时编译器为什么耗时当初咱们晓得服务部署时CPU飙高是因为触发了即时编译,而且即时编译是在用户程序运行的时候后盾执行的,可通过BackgroundCompilation参数设置,默认值是true,这个参数设置成false是很危险的操作,业务线程会期待即时编译实现,可能一个世纪曾经过来了。 那在后盾执行的过程中编译器都做了什么呢?大抵分为三个阶段,流程如下。 第一阶段:一个平台独立的前端将字节码结构成一种高级中间代码示意(High-Level Intermediate Representation, 简称HIR),HIR应用动态单分的模式来代表代码值,这能够使得一些在HIR的结构之中和之后进行的优化动作更容易实现。在此之前编译器会在字节码上实现一部分根底优化,比方办法内联、常量流传。 第二阶段:一个平台相干的后端从HIR中产生低级中间代码示意(Low-Level Intermediate Representation, 简称LIR),而在此之前会在HIR上实现另外一些优化,如空值查看打消、范畴查看打消等。 第三阶段:在平台相干的后端应用线性扫描算法(Liner Scan Register Allocation)在LIR上调配寄存器,并在LIR上做窥孔优化,而后产生机器代码。 以上阶段是C1编译器的大抵过程,而C2编译器会执行所有经典的优化动作,比方无用代码打消、循环展开、逃逸剖析等。 怎么解决问题晓得问题的根因,只须要隔靴搔痒即可,咱们最终的指标是服务在部署的时候不要影响上游的调用,所以要把即时编译的执行工夫和用户程序运行工夫避开,能够抉择在上游流量切入之前让热点代码触发即时编译,也就是咱们说的预热,实现形式比较简单,应用Spring提供的办法。对于整个服务大部分都是热点代码的,能够在JVM启动脚本中退出“-XX:-TieredCompilation -server”参数来敞开分层编译模式,启用C2编译器,而后在预热的代码中模仿调用一遍所有接口,这样在流量接入之前会先进行即时编译。须要留神并不是所有的代码都会进行即时编译,存储机器码的内存无限,过大的代码即便达到肯定次数也不会触发。而咱们大部分服务都合乎“二八定律”,所以还是抉择保留分层编译模式,在办法外部模仿调用热门代码,须要计算好分层模式下触发即时编译的阈值,也能够依据参数适当的调整阈值大小。 文|Shane关注得物技术,携手走向技术的云端

July 30, 2021 · 1 min · jiezi

关于服务:华为云专家原创-服务注册与发现如何满足服务治理

摘要:本文次要介绍了服务注册与发现的原理,以及罕用的几种服务注册与发现组件介绍比照。在单体利用向微服务架构演进的过程中,本来的巨石型利用会依照业务需要被拆分成多个微服务,每个服务提供特定的性能,并可能依赖于其余的微服务。每个微服务实例都能够动静部署,服务实例之间的调用通过轻量级的近程调用形式(HTTP、音讯队列等)实现,它们之间通过事后定义好的接口进行拜访。 因为服务实例是动静部署,每个服务实例的地址和服务信息都可能动态变化,势必须要一个中心化的组件对各个服务实例的信息进行治理,该组件治理了各个部署好的服务实例元数据,包含不仅限于服务名、IP 地址、端口号、服务形容和服务状态等。 什么是服务注册与发现?服务注册与发现次要蕴含两局部:服务注册与服务发现。服务注册是指服务实例启动时将本身信息注册到服务注册与发现核心,并在运行时通过心跳等形式向服务注册与发现核心汇报本身服务状态;服务发现是指服务实例向服务注册与发现核心获取其余服务实例信息,用于进行接下来的近程调用。接下来让咱们介绍服务注册与发现核心的职责和服务实例进行服务注册的根本流程,以及分布式系统中数据同步的基本原理 CAP。 服务注册与发现核心有什么性能?在传统单体利用中,利用都是部署在固定的物理机器或者云平台上,他们之间的调用个别是通过固定在代码外部或者配置文件的服务地址和端口间接发动。因为利用数量较少,系统结构复杂度不高,开发人员和运维人员能够较为轻松地进行治理和配置。 随着利用架构向微服务架构迁徙,服务数量的减少和动静部署动静扩大的个性,使得服务地址和端口在运行时是随时可变的。对此,咱们须要一个额定的中心化组件对立治理动静部署的微服务利用的服务实例元数据,个别称它为服务注册与发现核心。服务注册与发现核心次要有以下的职责: 治理以后注册到服务注册与发现核心的微服务实例元数据信息,包含服务实例的 服务名、IP 地址、端口号、服务形容和服务状态等;与注册到服务发现与注册核心的微服务实例维持心跳,定期检查注册表中的服务实例是否在线,并剔除有效服务实例信息;提供服务发现能力,为服务调用方提供服务提供方的服务实例元数据。通过服务发现与注册核心,能够很不便地管理系统中动态变化的服务实例信息。与此同时,它也可能成为零碎的瓶颈和故障点。因为服务之间的调用信息来自于服务注册与发现核心,当它不可用时,服务之间的调用可能无奈失常进行。因而服务发现与注册核心个别会集群化部署,提供高可用性和高稳定性。 分布式中的 CAP 实践在实质上来讲,微服务利用属于分布式系统的一种落地实际,而分布式系统最大的难点是解决各个节点之间数据状态的一致性。即便是提倡无状态的 HTTP RESTful API 申请,在解决多服务实例状况下的批改数据状态申请,也是须要通过数据库或者分布式缓存等内部系统维护数据的一致性。CAP 原理是形容分布式系统下节点数据同步的根本定理。 CAP 原理由加州大学的 Eric Brewer 传授提出,别离指 Consistency (一致性)、Availablity (可用性)、Partition tolerance (分区容忍性)。Eric Brewer 认为,以上三个指标最多同时满足两个。 Consistency,指数据一致性,示意一个零碎的数据信息(包含备份数据)在同一时刻都是统一的。在分布式系统下,同一份数据可能存在于多个不同的实例中,在数据强一致性的要求下,对其中一份数据的批改必须同步到它的所有备份中。在数据同步的任何时候,都须要保障所有对该份数据的申请将返回同样的状态。Availablity,指服务可用性,要求服务在承受到客户端申请后,都可能给出响应。服务可用性考量的是零碎的可用性,要求零碎在高并发状况下和局部节点宕机的状况下,零碎整体仍然可能响应客户端的申请。Partition tolerance,指分区容忍性。在分布式系统中,不同节点之间是通过网络进行通信。基于网络的不可靠性,位于不同网络分区的服务节点可能会通信失败,如果零碎可能容忍这种状况,阐明它是满足分区容忍性的。如果零碎不可能满足分区容忍性,那么将会限度分布式系统的扩展性,即服务节点的部署数量和地区都会受限,违反了分布式系统设计的初衷,所以一般来讲分布式系统都会满足分区容忍性。在满足了分区容忍性的前提下,分布式系统并不能同时满足数据一致性和服务可用性。假如服务A当初有两个实例A1和A2,它们之间的网络通信呈现了异样,基于分区容忍性,这并不会影响A1和A2独立的失常运行。如果此时客户端申请A1,申请将数据B从B1状态批改为B2,因为网络的不可用,数据B的批改并不能告诉到实例A2。如果此时另一个客户端向A2申请数据B,如果A2返回数据B1,将满足服务可用性,但并不能满足数据一致性;如果A2须要期待A1的告诉之后才可能返回数据B的正确状态,尽管满足了数据一致性,但并不能响应客户端申请,违反了服务可用性的指标。 基于分布式系统的根本特质,P 是必须要满足,接下来须要思考满足 C 还是 A。在相似银行之类对金额数据要求强一致性的零碎中,要优先思考满足数据一致性;而相似公众网页之类的零碎,用户对网页版本的新旧不会有特地的要求,在这种场景下服务可用性高于数据一致性。 如何抉择服务注册与发现框架?随着近几年微服务框架高速倒退,目前业界曾经开源出了大量优良的服务注册与发现组件,包含不仅限于 Consul、Etcd、Zookeeper、Eureka。它们之间各有千秋,在组件选型时能够依据本身业务的须要进行抉择和革新,接下来咱们次要对 Consul、Etcd、Zookeeper 作一些简略的介绍和比拟。 基于 Raft 算法、开箱即用的服务发现零碎 ConsulConsul 由 HashiCorp 开源,是反对多个平台的分布式高可用零碎。Consul 应用 Golang 语言实现,次要用于实现分布式系统的服务发现与配置,满足 AP 个性。Consul 是分布式、高可用和可横向扩大的,提供以下次要个性: 服务发现:能够应用 HTTP 或者 DNS 的形式将服务实例的元数据注册到 Consul,和通过 Consul 发现所依赖服务的元数据列表。查看查看:Consul 提供定时的健康检查机制,定时申请注册到 Consul 中的服务实例提供的健康检查接口,将异样返回的服务实例标记为不衰弱。Key/Value:Consul 提供了 Key/Value 存储性能,能够通过简略的 HTTP 接口进行应用。多数据中心:Consul 应用 Raft算法来保证数据一致性,提供了开箱即用的多数据中心性能。服务实例与 Consul 的交互如下图所示: ...

December 30, 2020 · 2 min · jiezi

关于服务:重磅解读K8s-Cluster-Autoscaler模块及对应华为云插件Deep-Dive

摘要:本文将解密K8s Cluster Autoscaler模块的架构和代码的Deep Dive,及K8s Cluster Autoscaler 华为云插件。背景信息基于业务团队(Cloud BU 利用平台)在开发Serverless引擎框架的过程中实现的K8s Cluster Autoscaler华为云插件。 目前该插件曾经奉献给了K8s开源社区,见下图: 本文将会波及到下述内容: 对K8s Cluster Autoscaler模块的架构和代码的Deep Dive,尤其是外围性能点的所波及的算法的介绍。K8s Cluster Autoscaler 华为云插件模块的介绍。作者自己参加K8s开源我的项目的一点心得。(如:何从开源社区获取信息和求助,在奉献开源过程中须要留神的点)直入主题,这里不再赘述K8s的基本概念。 什么是K8s Cluster Autoscaler (CA)?什么是弹性伸缩? 顾名思义是依据用户的业务需要和策略,主动调整其弹性计算资源的治理服务,其劣势有: 从利用开发者的角度:可能让应用程序开发者专一实现业务性能,无需过多思考零碎层资源从零碎运维者的角度:极大的升高运维累赘, 如果零碎设计正当能够实现“零运维”是实现Serverless架构的基石,也是Serverless的次要个性之一在具体解释CA概念之前,咋们先从宏观上理解一下K8s所反对的几种弹性伸缩形式(CA只是其中的一种)。 K8s反对的几种弹性伸缩形式: 注: 为了形容精确性,介绍上面几个要害概念时,先援用K8S官网解释镇一下场 :)。"简而言之"局部为作者自己的解读。 VPA (Vertical Pod Autoscaler)A set of components that automatically adjust the amount of CPU and memory requested by Pods running in the Kubernetes Cluster. Current state - beta. 简而言之: 对于某一个POD,对其进行扩缩容(因为应用场景不多,不做过多介绍) HPA(Horizontal Pod Autoscaler) - Pod级别伸缩A component that scales the number of pods in a replication controller, deployment, replica set or stateful set based on observed CPU utilization (or, with beta support, on some other, application-provided metrics). ...

November 9, 2020 · 2 min · jiezi

使用winsw部署Windows服务

仓库地址: https://github.com/kohsuke/winsw 下载地址: https://github.com/kohsuke/wi...安装说明https://github.com/kohsuke/wi... 下载winsw程序,选择对应版本。(WinSW.NET2.exe 或 WinSW.NET4.exe)安装.NET Framework。将WinSW.exe复制到自定义的目录,并重命名为test.exe同目录下创建test.xml。特别注意,xml和exe必须同名使用test.exe install安装服务。使用test.exe uninstall卸载服务。示例,配置springboot的服务<configuration> <id>lance</id> <name>lance(winsw)</name> <description>java</description> <executable>java</executable> <arguments>-server -Xms400m -Xmx400m -Xmn100m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xverify:none -XX:+DisableExplicitGC -Djava.awt.headless=true -jar "lance-1.2.0.jar"</arguments> <log mode="reset"/></configuration>命令说明E:\service>test.exe /?A wrapper binary that can be used to host executables as Windows servicesUsage: winsw [/redirect file] <command> [<args>] Missing arguments trigger the service modeAvailable commands:- 'install' - install the service to Windows Service Controller- 'uninstall' - uninstall the service- 'start' - start the service (must be installed before)- 'stop' - stop the service- 'restart' - restart the service- 'restart!' - self-restart (can be called from child processes)- 'status' - check the current status of the service- 'test' - check if the service can be started and then stopped- 'testwait' - starts the service and waits until a key is pressed then stops the service- 'version' - print the version info- 'help' - print the help info (aliases: -h,--help,-?,/?)Extra options:- '/redirect' - redirect the wrapper's STDOUT and STDERR to the specified fileWinSW 2.2.0.0More info: https://github.com/kohsuke/winswBug tracker: https://github.com/kohsuke/winsw/issues配置说明https://github.com/kohsuke/wi... ...

June 19, 2019 · 3 min · jiezi

net-开发系统服务入门

没有什么比官方文档更适合学习了。 在这,给出几点注意的事项: 开发过程按官方文档走一遍,大体就明白开发的思路了。当然也就清楚,这个服务如果想高度还是比较困难的,其它的非服务类程序,我们在VS就调试了。而服务开发后必须加入到系统服务中,真正的运行。这会使得我们陷入:开发 -> 生成 -> 安装 -> 生产环境调试 -> 再开发的怪圈中。 在实际的开发中,建立采用如下方案: 建立另外一个一般的可视化项目,在此项目中完成服务需要的所有功能。在可视化的项目的开发中,完成调试工作。开发完成后,将功能进行迁移。权限问题服务运行时,是可以使用LocalSystem权限的。而一般的可视化项目运行时,需要指定使用administrator权限。这就要求我们在开发过程中,增加运行环境的配置选项。如果当前环境是在服务中,则无需指定administrator权限。 Developer Common Promptinstallutil是需要在此工具下执行的,直接在cmd中打开会提示找不到相关的命令。然后此工作是需要使用管理员权限打开的,否则会出现安全错误。 在“安装”阶段发生异常。System.InvalidOperationException: 无法打开计算机“.”上的服务控制管理器。此操作可能需要其他特权。引发了内部异常 System.ComponentModel.Win32Exception,错误消息如下: 拒绝访问。。

June 18, 2019 · 1 min · jiezi

CNET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区。 文章目录C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载 (1)在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务) (2)C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案 (3)前言在上一篇文章《在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)》的最后,我给大家抛出了一个遗留的问题--在将TopshelfDemoService程序作为Windows服务安装的情况下,由它守护并启动的客户端程序是没有UI界面的。到这里,我们得分析为什么会出现这个问题,为什么在桌面应用程序模式下可以显示UI界面,而在服务模式下没有UI界面? 分析问题(Session 0 隔离)通过查阅资料,这是由于Session 0 隔离作用的结果。那么什么又是Session 0 隔离呢? 在Windows XP、Windows Server 2003 或早期Windows 系统时代,当第一个用户登录系统后服务和应用程序是在同一个Session 中运行的。这就是Session 0 如下图所示: 但是这种运行方式提高了系统安全风险,因为服务是通过提升了用户权限运行的,而应用程序往往是那些不具备管理员身份的普通用户运行的,其中的危险显而易见。 从Vista 开始Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。如下图所示: 这样使得Session 0 与其他Session 之间无法进行交互,不能通过服务向桌面用户弹出信息窗口、UI 窗口等信息。这也就是为什么刚才我说那个图已经不能通过当前桌面进行截图了。 潜在的问题解决方案在了解了Session 0 隔离之后,给出一些有关创建服务程序以及由服务托管的驱动程序的建议: 1、与应用程序通信时,使用RPC、命名管道等C/S模式代替窗口消息2、如果服务程序需要UI与用户交互的话,有两种方式:①用WTSSendMessage来创建一个消息框与用户交互②使用一个代理(agent)来完成跟用户的交互,服务程序通过CreateProcessAsUser创建代理。 并用RPC或者命名管道等方式跟代理通信,从而完成复杂的界面交互。3、应该在用户的Session中查询显示属性,如果在Session 0中做这件事,将会得到不正确的结果。4、明确地使用Local或者Global为命名对象命名,Local/为Session/<n>/BaseNamedObject/,Global/为BaseNamedObject/5、将程序放在实际环境中测试是最好的方法,如果条件不允许,可以在XP的FUS下测试。在XP的FUS下能工作的服务程序将很可能可以在新版系统中工作,注意XP的FUS下的测试不能检测到在Session 0下跟视频驱动有关的问题 本文我们的服务程序将通过CreateProcessAsUser创建代理来实现Session 0隔离的穿透。 在项目[TopshelfDemoService]中创建一个静态扩展帮助类ProcessExtensions.cs,代码如下: using System;using System.Runtime.InteropServices;namespace TopshelfDemoService{ /// <summary> /// 进程静态扩展类 /// </summary> public static class ProcessExtensions { #region Win32 Constants private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400; private const int CREATE_NO_WINDOW = 0x08000000; private const int CREATE_NEW_CONSOLE = 0x00000010; private const uint INVALID_SESSION_ID = 0xFFFFFFFF; private static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero; #endregion #region DllImports [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] private static extern bool CreateProcessAsUser( IntPtr hToken, String lpApplicationName, String lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandle, uint dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] private static extern bool DuplicateTokenEx( IntPtr ExistingTokenHandle, uint dwDesiredAccess, IntPtr lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); [DllImport("userenv.dll", SetLastError = true)] private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit); [DllImport("userenv.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr hSnapshot); [DllImport("kernel32.dll")] private static extern uint WTSGetActiveConsoleSessionId(); [DllImport("Wtsapi32.dll")] private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken); [DllImport("wtsapi32.dll", SetLastError = true)] private static extern int WTSEnumerateSessions( IntPtr hServer, int Reserved, int Version, ref IntPtr ppSessionInfo, ref int pCount); #endregion #region Win32 Structs private enum SW { SW_HIDE = 0, SW_SHOWNORMAL = 1, SW_NORMAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, SW_SHOWDEFAULT = 10, SW_MAX = 10 } private enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } [StructLayout(LayoutKind.Sequential)] private struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } private enum SECURITY_IMPERSONATION_LEVEL { SecurityAnonymous = 0, SecurityIdentification = 1, SecurityImpersonation = 2, SecurityDelegation = 3, } [StructLayout(LayoutKind.Sequential)] private struct STARTUPINFO { public int cb; public String lpReserved; public String lpDesktop; public String lpTitle; public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } private enum TOKEN_TYPE { TokenPrimary = 1, TokenImpersonation = 2 } [StructLayout(LayoutKind.Sequential)] private struct WTS_SESSION_INFO { public readonly UInt32 SessionID; [MarshalAs(UnmanagedType.LPStr)] public readonly String pWinStationName; public readonly WTS_CONNECTSTATE_CLASS State; } #endregion // Gets the user token from the currently active session private static bool GetSessionUserToken(ref IntPtr phUserToken) { var bResult = false; var hImpersonationToken = IntPtr.Zero; var activeSessionId = INVALID_SESSION_ID; var pSessionInfo = IntPtr.Zero; var sessionCount = 0; // Get a handle to the user access token for the current active session. if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref pSessionInfo, ref sessionCount) != 0) { var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); var current = pSessionInfo; for (var i = 0; i < sessionCount; i++) { var si = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO)); current += arrayElementSize; if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive) { activeSessionId = si.SessionID; } } } // If enumerating did not work, fall back to the old method if (activeSessionId == INVALID_SESSION_ID) { activeSessionId = WTSGetActiveConsoleSessionId(); } if (WTSQueryUserToken(activeSessionId, ref hImpersonationToken) != 0) { // Convert the impersonation token to a primary token bResult = DuplicateTokenEx(hImpersonationToken, 0, IntPtr.Zero, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)TOKEN_TYPE.TokenPrimary, ref phUserToken); CloseHandle(hImpersonationToken); } return bResult; } public static bool StartProcessAsCurrentUser(string appPath, string cmdLine = null, string workDir = null, bool visible = true) { var hUserToken = IntPtr.Zero; var startInfo = new STARTUPINFO(); var procInfo = new PROCESS_INFORMATION(); var pEnv = IntPtr.Zero; int iResultOfCreateProcessAsUser; startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO)); try { if (!GetSessionUserToken(ref hUserToken)) { throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed."); } uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | (uint)(visible ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW); startInfo.wShowWindow = (short)(visible ? SW.SW_SHOW : SW.SW_HIDE); startInfo.lpDesktop = "winsta0\\default"; if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false)) { throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed."); } if (!CreateProcessAsUser(hUserToken, appPath, // Application Name cmdLine, // Command Line IntPtr.Zero, IntPtr.Zero, false, dwCreationFlags, pEnv, workDir, // Working directory ref startInfo, out procInfo)) { iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error(); throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed. Error Code -" + iResultOfCreateProcessAsUser); } iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error(); } finally { CloseHandle(hUserToken); if (pEnv != IntPtr.Zero) { DestroyEnvironmentBlock(pEnv); } CloseHandle(procInfo.hThread); CloseHandle(procInfo.hProcess); } return true; } }}修改ProcessHelper.cs为如下代码: ...

May 24, 2019 · 4 min · jiezi

C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载

本文首发于码友网–一个专注.NET/.NET Core开发的编程爱好者社区。文章目录C#/.NET基于Topshelf创建Windows服务的系列文章目录:C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载 (1)在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务) (2)C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案 (3)前言对于使用Windows操作系统的人来说,Windows Service(Windows服务)应该不会陌生。在Windows操作系统中,我们可以在"运行"窗口中运行service.msc:即可打开一个查看Windows服务的窗口,如图:Windows服务基本都是一些后台运行的服务进程,没有UI界面,每个服务处理着各自独立的任务并且有专门的启动或者停止策略。所以,Windows服务在很多情况下会被用来者处理一些定时任务或者调度。那么,对于.NET的开发者来说,可不可以自己创建Windows服务呢,如何使用C#创建Windows服务呢?本文就为大家分享一种基于Topshelf创建的Windows服务的方法。创建Topshelf服务项目首先打开Visual Studio(本文使用的是Visual Studio 2019),打开新建项目的对话框,选择.NET Framework的控制台应用程序(Console App(.NET Framework)),如图:注:只可选择控制台应用程序点击"下一步",在项目名称中输入TopshelfDemoService,.NET Framework 选择4.6.2,其中选项根据自己情况填写即可,最后点击"创建"按钮。安装Topshelf组件在TopshelfDemoService项目中,打开Nuget包管理工具,搜索Topshelf,在搜索结果中选中Topshelf,点击"安装",如图:编写Topshelf服务的示例程序代码Topshelf组件安装完成后,我们就可以开始编写服务的示例代码了。首先,创建一个名为HealthMonitorService.cs的类(其作用假设为定时监控某个系统的运行健康状况),在其中分别创建方法:Start()和Stop()以及一个定时器,让定时器定时执行检查系统健康状况的任务(这里模拟的每秒向控制台输出一条文本信息),完整的代码如下:using System;using System.Timers;namespace TopshelfDemoService{ internal class HealthMonitorService { private readonly Timer _timer; public HealthMonitorService() { _timer = new Timer(1000) { AutoReset = true }; _timer.Elapsed += (sender, eventArgs) => Console.WriteLine(“执行系统健康检查任务,所有指标均正常。执行时间:{0}”, DateTime.Now); } public void Start() { _timer.Start(); } public void Stop() { _timer.Stop(); } }}再创建一个名为MyServiceConfigure.cs的服务配置类,这个类主要用来配置Topshelf服务的各种运行参数,代码如下:using System;using Topshelf;namespace TopshelfDemoService{ internal class MyServiceConfigure { internal static void Configure() { var rc = HostFactory.Run(host => // 1 { host.Service<HealthMonitorService>(service => // 2 { service.ConstructUsing(() => new HealthMonitorService()); // 3 service.WhenStarted(s => s.Start()); // 4 service.WhenStopped(s => s.Stop()); // 5 }); host.RunAsLocalSystem(); // 6 host.EnableServiceRecovery(service => // 7 { service.RestartService(3); // 8 }); host.SetDescription(“Windows service based on topshelf”); // 9 host.SetDisplayName(“Topshelf demo service”); // 10 host.SetServiceName(“TopshelfDemoService”); // 11 host.StartAutomaticallyDelayed(); // 12 }); var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); // 13 Environment.ExitCode = exitCode; } }}注:其中数字的含义请见本文末尾的解释。最后,打开Program.cs文件,开启Topshelf服务,如下:namespace TopshelfDemoService{ class Program { static void Main(string[] args) { MyServiceConfigure.Configure(); } }}好了,完成到这里,整个示例程序就写好了,按F5运行示例程序,你将看到如下类似的控制台信息:可以看到,我们创建的TopshelfDemoService服务每秒向控制台打印了一条文本信息,这和我们的预期是吻合的。这样,我们就成功创建了一个基于Topshelf的Windows服务,当然,这也只是一个简单和示例服务程序,其中没有复杂的业务逻辑和配置等等。这些都等待你去发掘。作为Windows服务安装和卸载我们刚才运行的只是一个控制台应用程序,如果将这个控制台应用程序关掉,定时任务也会被停止了。如果我们希望定时任务可以一直运行,那需要将这个控制台应用程序作为服务安装到Windows服务进程中,如何操作呢?非常简单的安装和卸载命令。首先,以管理员身份打开一个命令行工具,进入到控制台应用程序所在目录。安装安装服务运行如下命令:TopshelfDemoService.exe install打开Windows服务查看窗口(刷新),可以看到Topshelf demo service已经在服务列表中了,如图:这时,我们只需要按照Windows服务来操作这个服务即可。卸载如果需要卸载服务,则运行如下命令:TopshelfDemoService.exe uninstallTopshelf配置参数说明1.设置服务主机使用HostFactory.Run()来创建并运行一个Topshelft服务。2.设置Topshelf使用类型HealthMonitorService作为服务类。3.配置如何创建一个服务的实例,这里采用的是使用关键字new来实例化一个HealthMonitorService对象,你也可以使用IoCp容器来实例化服务对象。4.设置当服务启动时执行的操作。5.设置当服务停止时执行的操作。6.设置将服务以本地系统身份运行。7.启动恢复服务模式(当服务意外停止后自动恢复)。8.设置第一次自动恢复服务的延迟时间为3分钟。9.设置Topshelf服务在Windows服务中的描述信息。10.设置Topshelf服务在Windows服务中的显示名称。11.设置Topshelf服务在Windows服务中的服务名称。12.设置Topshelf服务随Windows启动时自动运行(延迟)。13.设置服务的退出代码。示例代码托管和下载本示例代码托管地址可以在原出处找到:示例代码下载地址 ...

April 12, 2019 · 1 min · jiezi