【总结】探索Newlife组件:服务代理利器XAgent的前世今生

时间:2022-01-13 03:58:43

      本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html

Newlife XCode组件相关文章目录:http://www.cnblogs.com/asxinyu/p/4329747.html

XAgent是新生命开发团队X组件的其中一个项目,石头今天在群里揭开了其神秘的面纱,很多的不懂和不解,总结成此文,以备后用。

1.XAgent的基本介绍

1.1 XAgent的来源

XAgent是一个服务代理程序,它出现的初衷,是为了解决写Windows服务不方便的问题。因为用Visual Stuido写的Windows服务程序,需要创建一个特殊的项目,安装的时候还需要特殊的命令,所以对新手来说,非常繁琐,跟令人讨厌的是不好调试(也许你有好的方法,但是要让更多人,短时间掌握是有难度的)。试问,多少人会去挂载一个Windows服务进程进行调试么?所以,XAgent横空出世!所谓Windows服务程序,一点也不特别,完完全全就是一个exe。

1.2 第一代XAgent

一个普通的应用程序,比如WinForm也可以做服务程序。XAgent是一个控制台写的exe程序,只不过它继承了Service类。控制器启动这个类,再用sc命令安装到服务里面,这样服务就可以很好的工作了。XAgent开头就检查参数,如果这个exe附带了参数,就进行特殊操作;如果没有参数,就启动一个菜单;没有参数的时候,就显示如下这个界面:

【总结】探索Newlife组件:服务代理利器XAgent的前世今生

2,4,5很重要。其中-i参数,就表示安装服务。有2种安装方式,1种是命令行 Test.exe -i;另一种是先启动Test.exe,然后按2键。按2以后,是下面这个样子:

【总结】探索Newlife组件:服务代理利器XAgent的前世今生

-i就可以把当前exe安装到服务里面,Test.exe -run,带有参数,这样子,Windows服务启动 的时候,其实是带有-run参数的。3就是启动了,所以,用XAgent,根本就不需要写安装卸载的脚本命令。重点看看4,5点功能:

XAgent的设计中,有一个大大的StartWork/StopWork,代表服务的开始和停止,循环调试调用的就是它们。StartWork里面开一个线程,定时调用Work(index)函数,单步调试就是调用Work,所以支持轮询式服务;如果用4,就调用一次work,相当于执行一次轮询。这样就很方便我们调试代码了,因为现在是控制台状态,而业务代码在work里面。所以业务代码可以供多个方面使用:
1.控制台调用
2.Windows服务调用
3.调试调用

在XAgent里面,只要你在控制台下调试业务代码没有问题,到了Windows服务里面,也没有问题,这就是第一代XAgent。

2.第二代XAgent

XAgent可以挂载无数个Windows服务,也就是它注册成为一个Windows服务程序,但是里面可以含有很多个服务。第一代XAgent很烂,但有很重要的意义。第二代XAgent,每个服务有自己的StartWork/Work(index)/StopWork。然后XAgent会启动一个管理线程,拥有最高优先级,每个服务的循环都有一个逻辑线程,普通优先级,管理线程会实时监控每一个工作线程的资源状况,以及整个服务程序的资源状况。配置文件有监控指标:

【总结】探索Newlife组件:服务代理利器XAgent的前世今生

如果工作线程超过时间没有向管理线程汇报,那么管理线程会把它干掉,重新启动XAgent.MaxActive,如果占用内存、线程数过高,XAgent干脆让整个服务重启XAgent.AutoRestart是自动重启时间;XAgent的重启绝对不是简单重启,它重启之前,会停止所有工作线程的轮询,也就是等每个线程完成当前的work(index)。一次轮询就是最小工作颗粒,只要你在这次work里面做好你的事情,就不会造成数据丢失。管理线程等所有线程的work完成了才会真正重启服务的,这是一个最高优先级的调度,避免有的工作线程开小灶,自己开线程不受管制,XAgent.AutoRestart就是定时重启的功能。理论上,99.9%的服务程序,只要每天得到重启一次,就可以无限的工作下去。

3.第三代XAgent

第二代XAgent还是不够完美,从第三代开始,加上了“看门狗”功能。看下图:

【总结】探索Newlife组件:服务代理利器XAgent的前世今生

双服务或者多个服务互相监视,每一个用XAgent做的服务程序都带有这个功能,真正的产品里面,最少用两个Windows服务,分为AB两个,A的看门狗监视B,B的看门狗监视A,谁也不会死;如果环境过于恶劣,你不妨多开几个小伙伴;XAgent的看门狗有漏洞,那就是,AB互相监视以后,谁也灭不了它……,你必须赶在另一个启动它之前把两个进程都干掉。其实可以开个小门的,发现特殊通道进去的就退出,不要监视,禁用也不行,XAgent会重新把它启用,这样子,用XAgent写的程序,就有了不死之身,所以我说XAgent是网络程序的最佳搭档。

XAgent修改架构,从DLL变成了Exe,因为XAgent已经很成熟,没有什么必要扩展了。我们要写Windows服务的时候,只需要建立一个类,实现IService接口,这个接口在核心库里面,然后在XAgent配置文件配置一下,XAgent就会加载你的服务类,直接启动,我们自己根本就不用写exe项目。比如我们做一个网站,突然要用到一个很小的功能,需要Windows服务,这个时候,我们干脆在业务类库里面加上一个实现了IService的类,配置好XAgent,XAgent就可以安装Windows服务了,这就是第三代XAgent。

4.总结

1.它自身是控制台程序,可以注册成为Windows服务,但是,它带有WinForm类,可以在登录用户的右下角有个小图标,用户可以通过它呼出一个WinForm设置界面,然后你就可以做你想做的事情。

2.XAgent在实现一个简单的HttpServer,支持用户通过浏览器访问控制服务,不支持ASP.Net,但是支持XTemplate;有了这个HttpServer,XAgent就可以分布式协同调度了。

看一段示例代码吧,关于X组件的其他和下载可以看我的博客其他文章。

 namespace XAgent
{
/// <summary>代理服务例子。自定义服务程序可参照该类实现。</summary>
class AgentService : AgentServiceBase<AgentService>
{
#region 属性
/// <summary>线程数</summary>
public override int ThreadCount { get { return ; } } /// <summary>显示名</summary>
public override string DisplayName { get { return "新生命服务代理"; } } /// <summary>描述</summary>
public override string Description { get { return "用于承载各种服务的服务代理!"; } }
#endregion #region 构造函数
/// <summary>实例化一个代理服务</summary>
public AgentService()
{
// 一般在构造函数里面指定服务名
ServiceName = "XAgent";
}
#endregion #region 核心
/// <summary>核心工作方法。调度线程会定期调用该方法</summary>
/// <param name="index">线程序号</param>
/// <returns>是否立即开始下一步工作。某些任务能达到满负荷,线程可以不做等待</returns>
public override bool Work(int index)
{
// XAgent讲开启ThreadCount个线程,0<index<ThreadCount,本函数即为每个任务线程的主函数,间隔Interval循环调用
//WriteLine("任务{0},当前时间:{1}", index, DateTime.Now); return false;
}
#endregion
}
}