[2]jenkins部署.net平台自动化构建
在引入自动化部署工具的时候,我们对比了jenkins和gitlab CI,jenkins有非常丰富的插件,配置起来方便。gitlab CI更倾向于脚本配置,当然jenkins也可以使用pipeline实现全脚本化配置(everything is code,哈哈)。我们这里主要讲述jenkins的自动化部署。 基本组合是jenkins+git+msbuild+python,实现从代码仓库拉取、编译、打包、部署、自动化测试。(.net core和framework4.6.1可以不依赖msbuild构建,将在下一篇文章中讲述) 一、安装环境 1.jenkins是java生态圈的产品,需要安装jdk 2..net项目依赖.net framework,安装需要的framework版本(如framework4.5.1) 3.安装构建工具msbuild 4.安装nuget 5.安装jenkins 二、配置jenkins 1.安装好jenkins后,进入“系统管理”->“插件管理”,安装git和msbuild这两款插件。 2.安装好插件后,新建一个项目,选择“构建一个自由风格的软件项目”,然后点确定。 3.源码管理选择git。 4.添加构建步骤,构建一个项目 5.项目需要nuget获取程序包的,可以使用批处理来实现,继续添加构建步骤: 6.nuget restore 命令获取项目需要程序包 Rebulid:构建 Configuratiom = Release:按release打包 DeployOnBuild = true/false:是否打包 PublishProfile=pub100:pub100是VS打包的配置文件 注意:这里的Msbuild Version选择了vs2017里的,jenkins插件库中的msbuild版本太低,编译经常出错,最简单的做法就是安装VS,然后在“系统管理”->“全局工具配置”中配置VS工具中的msbuild路径 7.构建触发器,jenkins提供定时构建及轮询机制。轮询是设置一段时间间隔,去代码仓库检测是否有更新,有更新触发构建。 8.保存,选择“立即构建” 9.构建成功 10.控制台日志 部署服务器和自动化测试都由python实现,感兴趣的可以看我另外一篇文章。 from:https://www.cnblogs.com/shenh/p/8946404.html
View Details[1]jenkins 持续部署 .net 服务
非真实项目,就是熟悉使用jenkins 一、要做什么 入门教程,所以啰嗦点,基础点。 如上图: 有一台公网的linux服务器,一台家里的pc(develop1)和一台家里的笔记本电脑(develop2)。还有工程是存储在开源中国上。 要实现的功能就是: 通过jenkins启动一个job,这个job会被分配到从机slave(develop1)上 然后develop1会从git上下载项目,并且使用msbuild编译项目,利用winrar打包项目 将上一步打包好的项目发送到develp2上 在develop2上解压项目,调用脚本进行部署服务 二、把jenkins跑起来 这里使用docker来部署jenkins,docker最厉害的地方就是部署方便,当然jenkins在windows上的部署也很方便容易,主要就是为了学习docker。.Net程序的编译最好还是在开发机上,因为开发机上的编译环境最全,基本上装了vs就都有了。如果想单独弄一台服务器专门用于编译.Net项目,并且不想装vs,那可能要费点功夫在编译环境的搭建上了。使用jenkins有一个重要的思想就是jenkins扮演的是调度者的身份,把一些零碎的工作串联起来。 当初第一次把jenkins跑起来,我居然天真的以为可以用jenkins编译.Net项目,因为jenkins上会装一个MSBuild的插件。然而并不是这样滴,因为jenkins仅仅是一个调度者的身份,具体干事的还是这些从机,或者本机的一些编译命令。 在Ubuntu上安装Docker照着教程弄,还是很容易。 下载jenkins镜像,并且在Docker上运行起来,这里怎么下载怎么用都有详细说明,仔细看看 访问jenkins页面,设置一个账户,一些基本的插件安装,之后就能看到这个页面了 三、配置节点(从机) 先配置开发机,也是编译用的机器develop1。 看到jenkins左边的菜单项:系统管理->管理节点->新建节点 输入一个节点名称,选中Permanent Agent,点击ok进入节点的详细配置页面 远程工作目录:就是从机的一个文件夹,这里要写绝对路径,我的就配置成:E:\jenkins_node 标签:相当于一个分组,多个从机可以分配到同一个标签下,我们这里用得少,就一个从机一个标签了,配置成node1 用法:因为只有这台机子可以编译.Net项目,所以配置成只允许运行绑定到这台机器的job 启动方法:这个后面有个帮助文档,点开可以看一下,选Launch agent via Java Web Start,这个的话就是要在从机上运行一个java的文件,这个东西就是一个代理,他会和jenkins服务器建立一条TCP通道,各种命令的传输,文件的拷贝就是通过这个代理和服务器建立的通道完成的。 Availability:选择keep this agent online as much as possible 然后保存,看到节点列表如下: 点击develop1,看到如下: 点击Launch这个按钮,会下载一个文件下来,slave-agent.jnlp,这个东西需要从机安装Java才能运行。安装好java之后,双击这个文件,就能运行起来,但是在网页节点列表上还是显示链接失败。这个时候看上图,还有一个方法Run from agent command line:,下面有个slave.jar包,下载下来,运行整个java命令,注意路径问题。之后就会显示连接上了。再用刚才我们的那个slave-agent.jnlp文件运行,发现也能链接上了。这个时候去看一下E:\jenkins_node,发现里面已经多了一些东西了。一个从机节点的配置就是如此,另外一台用于部署的机器也是如此,这里就略过了。 三、工程:一个毫无用处的服务 这里就是为了演示服务的部署,所以具体做什么不重要。但有个东西很好用,需要说一下,就是这个Topshelf。这个东西最厉害的地方就是能很容易地把一个控制台应用程序包装成服务运行起来,调试的时候使用控制台输出观察,具体要部署的时候,只需要在控制台应用程序.exe后加参数,就能运行为服务。可以看下教程,很简短,因为使用很简单。所以这里直接贴代码了。 DoServie.cs
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public class DoService { public void Start() { } public void Stop() { } } |
Program.cs
|
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 |
class Program { static void Main(string[] args) { HostFactory.Run(config => { config.Service<DoService>((setting) => { setting.ConstructUsing(x => new DoService()); setting.WhenStarted(x => x.Start()); setting.WhenStopped(x => x.Stop()); }); config.StartAutomatically(); config.EnableServiceRecovery(recoveryConfig => { recoveryConfig.RestartService(0); }); config.SetDescription("test Jenkins"); config.SetDisplayName("testJenkins"); config.SetServiceName("testJenkins"); }); } } |
安装服务的脚本install.bat,先卸载以前的服务,再安装服务,再启动,这个%~dp0就是dos下的一些变量吧,意思是bat文件所在路径
|
1 2 3 4 5 |
%~dp0DoNothingService.exe uninstall %~dp0DoNothingService.exe install %~dp0DoNothingService.exe start |
卸载服务的脚本uninstall.bat
|
1 |
%~dp0DoNothingService.exe uninstall |
好,把这个东西上传到开源中国上。 四、在jenkins上配置一个编译.Net项目的job 回到主界面 菜单列表:新建,如下: 选择第一项,构建一个自由风格的软件项目,ok确定,进入到详细配置页面 这个页面先用到基本的3个模块==Genera,源码管理,构建== General 基本信息里要注意红框中的部分,它的意思就是指定这个Job在哪个节点上运行,还记得我们上面创建的从机node1么,这里就是指定这个Job会交到node1上来执行。 源码管理 我这个项目是公开的,所以不需要身份验证信息,如果你的是私有项目,把账号密码填写一下就可以了。再有一个就是注意分支。源码管理就配置完了。 构建 再说构建之前,需要安装一个插件。先保存一下这个工程的配置。然后回到主菜单:系统管理->管理插件->可选插件,找到MSBuild Plugin,安装,稍等片刻,回到刚才工程的配置。 在构建下选择Build a Visual Studio project or solution using MSBuild,填写Command Line Arguments就行了,这里要注意一个路径问题,解决方案文件所在的路径,这里可以保存后,在项目页面点击立即构建,在里面看输出日志,哪里不对,慢慢调试。此时,node1下的路径为*E:\jenkins_node\workspace\NetServer*,这个节点代理从开源中国上把项目下载到了工作目录下,所以,编译参数的路径是以NetServer开始的。试几次之后,基本就能编译通过了。 注意: 从机需要安装git。 编译成功之后,我们得到了一堆.exe和dll,显然不利于传输,我们就用WinRar打个包,开发机要装winrar哦,并且添加到系统路径中。打包肯定是在编译成功之后执行的步骤,所以我们再增加一个构建步骤,并选择Execute Windows batch command,把我们的打包命令添加到当中 进入到输出文件目录,把Release文件夹打包为release.rar,注意-ibck参数是让winrar在后台运行。 […]
View Detailswin10 2016 长期服务版激活
win10 2016 长期服务版的ISO文件中本身就带有KMS激活KEY,不用输入任何KEY,连接网络进入CMD,只要输入: slmgr /skms kms.digiboy.ir slmgr /ato 这两条命令,就可以KMS激活。 来源:https://blog.csdn.net/chaoyu168/article/details/79241506,版权归原作者所有。 from:https://blog.csdn.net/realdenny/article/details/79860701
View DetailsDocker与CI持续集成/CD
背景 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,毕竟快速运转的互联网公司人力成本会高于机器,投资机器优化开发流程化相对也提高了人的效率,让 engineering productivity 最大化。 OpenShift是红帽的云开发平台即服务(PaaS)。自由和开放源码的云计算平台使开发人员能够创建、测试和运行他们的应用程序,并且可以把它们部署到云中。Openshift广泛支持多种编程语言和框架,如Java,Ruby和PHP等。另外它还提供了多种集成开发工具如Eclipse integration,JBoss Developer Studio和 Jenkins等。OpenShift 基于一个开源生态系统为移动应用,数据库服务等,提供支持。 Cloud Foundry是VMware推出的业界第一个开源PaaS云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。同时,它本身是一个基于Ruby on Rails的由多个相对独立的子系统通过消息机制组成的分布式系统,使平台在各层级都可水平扩展,既能在大型数据中心里运行,也能运行在一台桌面电脑中,二者使用相同的代码库。 Heroku作为最开始的云平台之一,从2007年6月起开发,当时它仅支持Ruby,但后来增加了对Java、Node.js、Scala、Clojure、Python以及(未记录在正式文件上)PHP和Perl的支持。基础操作系统是Debian,在最新的堆栈则是基于Debian的Ubuntu。 Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。 Cloudify 是一个云应用的编排系统,可让你的应用自动化的在各种不同的云上方便的部署。 正题 —————————————————————————————————————————————————————————————————————————— 希望对您系统架构,软件项目开发,运维管理,系统架构与研发管理体系, 信息安全, 企业信息化等有帮助。 其它您可能感兴趣的文章: 容器化实践金融业案例一 云计算参考架构几例 微服务与Docker介绍 互联网直播平台架构案例一 高可用架构案例一 某互联网公司广告平台技术架构 某大型电商云平台实践 云计算参考架构几例 移动应用App测试与质量管理一 全面的软件测试 著名ERP厂商的SSO单点登录解决方案介绍一 软件项目风险管理介绍 企业项目化管理介绍 智能企业与信息化之一 由企业家基本素质想到的 敏捷软件质量保证的方法与实践 构建高效的研发与自动化运维 IT运维监控解决方案介绍 IT持续集成之质量管理 人才公司环境与企业文化 企业绩效管理系统之平衡记分卡 企业文化、团队文化与知识共享 高效能的团队建设 餐饮连锁公司IT信息化解决方案一 from:https://www.cnblogs.com/wintersun/p/6258900.html
View DetailsC#中将字符串通过GZipStream进行压缩时的注意事项
背景, 今天在写代码时要用到GZipStream来压缩需要Web传输的数据块。原本以为GZipStream Write ->Flush ->读取对应MemoryStream数据就Okay的事情,却总是得不到正确的结果。 研究, 经过查询MSDN,原来只有在GZipStream被Dispose后,对应的MemoryStream中才会有真正的压缩数据被写入。 以下是我用来测试的代码片段(红色部分为原来的错误调用,橙色部分是正确的调用方式) string data = "<Root><PIGContent>test</PIGContent><RemoteUrl>http://www.a.com</RemoteUrl></Root>"; byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(data); byte[] compressedbuffer = null; //Compress buffer MemoryStream ms = new MemoryStream(); using(GZipStream zs = new GZipStream(ms, CompressionMode.Compress,true)) { zs.Write(buffer, 0, buffer.Length); //下面两句被注释掉的代码有问题, 对应的compressedbuffer的长度只有10--该10字节应该只是压缩buffer的header //zs.Flush(); //compressedbuffer = ms.ToArray(); } //只有GZipStream在Dispose后调应对应MemoryStream.ToArray()所得到的Buffer才是我们需要的结果 compressedbuffer = ms.ToArray(); 总结, 相信大家都会对GZipstream这种别扭的操作方式表示不满,微软对此也表示过歉意,但是由于其考虑到要兼容就的代码,因此即使在.Net 4.5中你还是得忍受这种不和谐的代码。 本篇小结如有不妥之处,烦请指正。 from: https://blog.csdn.net/missautumn/article/details/8351296
View DetailsJMeter入门
Jmeter简介 Jmeter的基本概念 百度百科: Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言 我们为什么使用Jmeter 开源免费,基于Java编写,可集成到其他系统可拓展各个功能插件 支持接口测试,压力测试等多种功能,支持录制回放,入门简单 相较于自己编写框架或其他开源工具,有较为完善的UI界面,便于接口调试 多平台支持,可在Linux,Windows,Mac上运行 Jmeter安装配置 Windows下Jmeter下载安装 登录 http://jmeter.apache.org/download_jmeter.cgi ,根据自己平台,下载对应文件 安装JDK,配置环境变量(具体步骤不做介绍) 将下载Jmeter文件解压,打开/bin/jmeter.bat 其他平台安装Jmeter 与Windows平台一致,除入口文件不同,例如linux平台下为/bin/jmeter.sh Jmeter的目录结构 /bin 目录(常用文件介绍) examples:目录下包含Jmeter使用实例 ApacheJMeter.jar:JMeter源码包 jmeter.bat:windows下启动文件 jmeter.sh:Linux下启动文件 jmeter.log:Jmeter运行日志文件 jmeter.properties:Jmeter配置文件 jmeter-server.bat:windows下启动负载生成器服务文件 jmeter-server:Linux下启动负载生成器文件 /docs目录——Jmeter帮助文档 /extras目录——提供了对Ant的支持文件,可也用于持续集成 /lib目录——存放Jmeter依赖的jar包,同时安装插件也放于此目录 /licenses目录——软件许可文件,不用管 /printable_docs目录——Jmeter用户手册 Jmeter相关插件安装: 插件安装: Jmeter的插件安装很简单,只需要下载对应插件解压即可。 下载地址:http://jmeter-plugins.org/downloads/all/ 下载后解压放入:apache-jmeter-2.12\lib\ext\目录下 重启jmeter ps:数据库链接驱动如果需要需要专门下载,例如mysql需要jdbc的jar包,地址:http://dev.mysql.com/downloads/file/?id=462850 使用注意事项:添加第三方插件并使用后保存的jmx文件在未添加该插件的运行环境下会导致无法打开该文件并报错,请保持环境一致性。 用例生成与导出: Jmeter的用例格式为jmx文件,实际为xml格式,感兴趣可以学习下自己定制生成想要的jmx文件。 生成原则: 每个功能模块为一个独立的jmx文件。增加可维护性。(尽量不要将一个jmx文件放入太多功能,后期维护成本会很高。) 模块的私有变量保存在模块中,多模块共有的(例如服务器ip端口等)可以考虑存在单独的文件中读取。 接口测试不要放太多线程,毕竟不是做压力测试,意义也不大。 导出方法: 编写测试用例 文件——保存为——确定: Jmeter常用文件类型 Jmx文件 文件的实际类型:xml 文件样本: <jmeterTestPlan version="1.2" properties="1.8"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test" enabled="true"> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> <boolProp […]
View Details获取CPU、内存、磁盘、进程信息
|
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Management; using System.Runtime.InteropServices; using System.Text; namespace ConsoleApp1 { /// /// 系统信息类 - 获取CPU、内存、磁盘、进程信息 /// public class SystemInfo { private int m_ProcessorCount = 0; //CPU个数 private PerformanceCounter pcCpuLoad; //CPU计数器 private long m_PhysicalMemory = 0; //物理内存 private const int GW_HWNDFIRST = 0; private const int GW_HWNDNEXT = 2; private const int GWL_STYLE = (-16); private const int WS_VISIBLE = 268435456; private const int WS_BORDER = 8388608; #region AIP声明 [DllImport("IpHlpApi.dll")] extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder); [DllImport("User32")] private extern static int GetWindow(int hWnd, int wCmd); [DllImport("User32")] private extern static int GetWindowLongA(int hWnd, int wIndx); [DllImport("user32.dll")] private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize); [DllImport("user32", CharSet = CharSet.Auto)] private extern static int GetWindowTextLength(IntPtr hWnd); #endregion #region 构造函数 /// /// 构造函数,初始化计数器等 /// public SystemInfo() { //初始化CPU计数器 pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total"); pcCpuLoad.MachineName = "."; pcCpuLoad.NextValue(); //CPU个数 m_ProcessorCount = Environment.ProcessorCount; //获得物理内存 ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if (mo["TotalPhysicalMemory"] != null) { m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString()); } } } #endregion #region CPU个数 /// /// 获取CPU个数 /// public int ProcessorCount { get { return m_ProcessorCount; } } #endregion #region CPU占用率 /// /// 获取CPU占用率 /// public float CpuLoad { get { return pcCpuLoad.NextValue(); } } #endregion #region 可用内存 /// /// 获取可用内存 /// public long MemoryAvailable { get { long availablebytes = 0; //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory"); //foreach (ManagementObject mo in mos.Get()) //{ // availablebytes = long.Parse(mo["Availablebytes"].ToString()); //} ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString()); } } return availablebytes; } } #endregion #region 物理内存 /// /// 获取物理内存 /// public long PhysicalMemory { get { return m_PhysicalMemory; } } #endregion #region 获得分区信息 /// /// 获取分区信息 /// public List<DiskInfo> GetLogicalDrives() { List<DiskInfo> drives = new List<DiskInfo>(); ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk"); ManagementObjectCollection disks = diskClass.GetInstances(); foreach (ManagementObject disk in disks) { // DriveType.Fixed 为固定磁盘(硬盘) if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } /// /// 获取特定分区信息 /// /// 盘符 public List<DiskInfo> GetLogicalDrives(char DriverID) { List<DiskInfo> drives = new List<DiskInfo>(); WqlObjectQuery wmiquery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = ’" + DriverID + ":’"); ManagementObjectSearcher wmifind = new ManagementObjectSearcher(wmiquery); foreach (ManagementObject disk in wmifind.Get()) { if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } #endregion #region 获得进程列表 /// /// 获得进程列表 /// public List<ProcessInfo> GetProcessInfo() { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcesses(); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } /// /// 获得特定进程信息 /// /// 进程名称 public List<ProcessInfo> GetProcessInfo(string ProcessName) { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcessesByName(ProcessName); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } #endregion #region 结束指定进程 /// /// 结束指定进程 /// /// 进程的 Process ID public static void EndProcess(int pid) { try { Process process = Process.GetProcessById(pid); process.Kill(); } catch { } } #endregion #region 查找所有应用程序标题 /// /// 查找所有应用程序标题 /// /// 应用程序标题范型 public static List<string> FindAllApps(int Handle) { List<string> Apps = new List<string>(); int hwCurr; hwCurr = GetWindow(Handle, GW_HWNDFIRST); while (hwCurr > 0) { int IsTask = (WS_VISIBLE | WS_BORDER); int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE); bool TaskWindow = ((lngStyle & IsTask) == IsTask); if (TaskWindow) { int length = GetWindowTextLength(new IntPtr(hwCurr)); StringBuilder sb = new StringBuilder(2 * length + 1); GetWindowText(hwCurr, sb, sb.Capacity); string strTitle = sb.ToString(); if (!string.IsNullOrEmpty(strTitle)) { Apps.Add(strTitle); } } hwCurr = GetWindow(hwCurr, GW_HWNDNEXT); } return Apps; } #endregion } public class DiskInfo { public DiskInfo() { } public DiskInfo(string name, long size, long freeSpace) { this.Name = name; this.Size = size; this.FreeSpace = freeSpace; } public string Name { get; set; } public long Size { get; set; } public long FreeSpace { get; set; } } public class ProcessInfo { public ProcessInfo() { } public ProcessInfo(int id, string processName, double totalMilliseconds, long workingSet64, string fileName) { Id = id; ProcessName = processName; TotalMilliseconds = totalMilliseconds; WorkingSet64 = workingSet64; FileName = fileName; } public int Id { get; set; } public string ProcessName { get; set; } public double TotalMilliseconds { get; set; } public long WorkingSet64 { get; set; } public string FileName { get; set; } } } |
参考: https://www.cnblogs.com/zery/p/6256850.html https://www.cnblogs.com/maowang1991/archive/2013/08/27/3285983.html
View DetailsC#读取Windows日志
管理-->事件查看器 可以查看【应用程序】、【安全】、【系统】等分类的日志
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
static void Main(string[] args) { EventLog eventlog = new EventLog(); eventlog.Log = "Security"; //"Application"应用程序, "Security"安全, "System"系统 EventLogEntryCollection eventLogEntryCollection = eventlog.Entries; foreach (EventLogEntry entry in eventLogEntryCollection) { //if (entry.EventID == 4624) //{ // continue; //} string info = string.Empty; if (@"TaskScheduler" == entry.Source.ToString()) { info += "类型:" + entry.EntryType.ToString() + ";"; info += "日期" + entry.TimeGenerated.ToLongDateString() + ";"; info += "时间" + entry.TimeGenerated.ToLongTimeString() + ";"; info += "来源" + entry.Source.ToString() + ";"; Console.WriteLine(info); } } } |
from:https://www.cnblogs.com/gossip/p/5249982.html
View DetailsWeb获取服务器信息以及监控服务器
准备工作: Hyperic-hq官方网站:http://www.hyperic.com Sigar.jar下载地址:http://sourceforge.net/projects/sigar/files/ Sigar.jar文档地址:https://support.hyperic.com/display/SIGAR/Home 介绍 Sigar全名是System Information Gatherer And Reporter,中文名是系统信息收集和报表工具。我是一个开源的工具,提供了跨平台的系统信息收集的API ,是Hyperic-hq产品的基础包,是Hyperic HQ主要的数据收集组件。它用来从许多平台收集系统和处理信息。 这些平台包括:Linux,Windows,Solaris,AIX,HP-UX,FreeBSD和Mac OSX。 可以收集的信息 CPU信息:包括基本信息(vendor、model、mhz、cacheSize)和统计信息(user、sys、idle、nice、wait) 文件系统信息:包括Filesystem、Size、Used、Avail、Use%、Type 事件信息:类似Service Control Manager 内存信息:物理内存和交换内存的总数、使用数、剩余数;RAM的大小 网络信息:包括网络接口信息和网络路由信息 进程信息:包括每个进程的内存、CPU占用数、状态、参数、句柄 IO信息:包括IO的状态,读写大小等 服务状态信息 系统信息:包括操作系统版本,系统资源限制情况,系统运行时间以及负载,JAVA的版本信息等 使用 Sigar有C,C#,Java和Perl API,java版的API为sigar.jar。sigar.jar的底层是用C语言编写的,它通过本地方法来调用操作系统API来获取系统相关数据。 Windows操作系统下Sigar.jar 依赖sigar-amd64-winnt.dll或sigar-x86-winnt.dll linux 操作系统下则依赖libsigar-amd64-linux.so或libsigar-x86-linux.so。 具体的对应关系如下: File Language Description Required sigar.jar Java Java API Yes log4j.jar Java Java logging API No libsigar-x86-linux.so C Linux AMD/Intel 32-bit * libsigar-amd64-linux.so C Linux AMD/Intel 64-bit * libsigar-ppc-linux.so C Linux PowerPC 32-bit * libsigar-ppc64-linux.so C Linux PowerPC 64-bit * libsigar-ia64-linux.so C Linux Itanium 64-bit * libsigar-s390x-linux.so C Linux zSeries 64-bit * sigar-x86-winnt.dll C Windows AMD/Intel 32-bit * sigar-amd64-winnt.dll C Windows AMD/Intel 64-bit * libsigar-ppc-aix-5.so C AIX PowerPC 32-bit * libsigar-ppc64-aix-5.so C […]
View Detailsphp-fpm配置优化
前言: 1.少安装PHP模块, 费内存 2.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号)(我是修改/etc/rc.local,加入ulimit -SHn 51200的)
|
1 2 3 |
echo `ulimit -HSn 65536` >> /etc/profile echo `ulimit -HSn 65536` >> /etc/rc.local source /etc/profile |
如果ulimit -n数量依旧不多(即上面配置没生效)的话, 可以在 /etc/security/limits.conf 文件最后加上
|
1 2 |
* soft nofile 51200 * hard nofile 51200 |
1.与Nginx使用Unix域Socket通信(Nginx和php-fpm在同一台服务器) Unix域Socket因为不走网络,的确可以提高Nginx和php-fpm通信的性能,但在高并发时会不稳定。 Nginx会频繁报错:connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream 可以通过下面两种方式提高稳定性: 1)调高nginx和php-fpm中的backlog 配置方法为:在nginx配置文件中这个域名的server下,在listen 80后面添加default backlog=1024。 同时配置php-fpm.conf中的listen.backlog为1024,默认为128。 2)增加sock文件和php-fpm实例数 再新建一个sock文件,在Nginx中通过upstream模块将请求负载均衡到两个sock文件背后的两套php-fpm实例上。 2.php-fpm参数调优 pm = dynamic; 表示使用哪种进程数量管理方式 dynamic表示php-fpm进程数是动态的,最开始是pm.start_servers指定的数量,如果请求较多,则会自动增加,保证空闲的进程数不小于pm.min_spare_servers,如果进程数较多,也会进行相应清理,保证多余的进程数不多于pm.max_spare_servers static表示php-fpm进程数是静态的, 进程数自始至终都是pm.max_children指定的数量,不再增加或减少 pm.max_children = 300; 静态方式下开启的php-fpm进程数量 pm.start_servers = 20; 动态方式下的起始php-fpm进程数量 pm.min_spare_servers = 5; 动态方式下的最小php-fpm进程数量 pm.max_spare_servers = 35; 动态方式下的最大php-fpm进程数量 如果pm为static, 那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程 如果pm为dynamic, 那么pm.max_children参数失效,后面3个参数生效。系统会在php-fpm运行开始的时候启动pm.start_servers个php-fpm进程,然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数 那么,对于我们的服务器,选择哪种pm方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。 对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。这样可以保证php-fpm只获取够用的内存,将不多的内存分配给其他应用去使用,会使系统的运行更加畅通。 对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩溃就应该很正常了。因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者使用动态方式,因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间。 在4G内存的服务器上200就可以(我的1G测试机,开64个是最好的,建议使用压力测试获取最佳值) pm.max_requests = 10240; nginx php-fpm配置过程中最大问题是内泄漏出问题:服务器的负载不大,但是内存占用迅速增加,很快吃掉内存接着开始吃交换分区,系统很快挂掉!其实根据官方的介绍,php-cgi不存在内存泄漏,每个请求完成后php-cgi会回收内存,但是不会释放给操作系统,这样就会导致大量内存被php-cgi占用。 官方的解决办法是降低PHP_FCGI_MAX_REQUESTS的值,如果用的是php-fpm,对应的php-fpm.conf中的就是max_requests,该值的意思是发送多少个请求后会重启该线程,我们需要适当降低这个值,用以让php-fpm自动的释放内存,不是大部分网上说的51200等等,实际上还有另一个跟它有关联的值max_children,这个是每次php-fpm会建立多少个进程,这样实际上的内存消耗是max_children*max_requests*每个请求使用内存,根据这个我们可以预估一下内存的使用情况,就不用再写脚本去kill了。 request_terminate_timeout = 30; 最大执行时间, 在php.ini中也可以进行配置(max_execution_time) request_slowlog_timeout = 2; 开启慢日志 slowlog = log/$pool.log.slow; 慢日志路径 rlimit_files = 1024; 增加php-fpm打开文件描述符的限制 3.php-fpm的高CPU使用率排查方法 1)使用top命令, 直接执行top命令后,输入1就可以看到各个核心的CPU使用率。而且通过top […]
View Details