xframe的服务加载流程
1. 数据转发服务的运行与加载
先用数据转发服务来说明一下一个普通的服务的运行加载过程
数据库配置表结构如下:
| Column | 含义 |
|---|---|
| id | 主键id |
| src_ip | 数据源IP |
| src_port | 数据源端口 |
| src_type | 通讯协议 ,0:TCP SERVER,1:TCP CLIENT |
| des_ip | 目的源IP |
| des_port | 目的源端口 |
| des_type | 通讯协议,0:TCP SERVER,1:TCP CLIENT |
一个转发器Transit对象结构应当如下
| Transit | 转发器对象 |
|---|---|
| src_tcp | 源TCP实例,由src相关属性生成 |
| des_tcp | 目的TCP实例,由des相关属性生成 |
假如当前配置表如下
| id | src_ip | src_port | src_type | des_ip | des_port | des_type |
|---|---|---|---|---|---|---|
| 1 | 127.0.0.1 | 10001 | 0 | 127.0.0.1 | 20001 | 0 |
| 2 | 127.0.0.1 | 10002 | 0 | 127.0.0.1 | 20002 | 0 |
数据转发服务运行的流程如下
从本地配置读取数据库连接配置(url,user,password等),连接到数据库
DatabaseConfig databaseConfig=Config.parser(); Database database=Connect(databaseConfig);读取数据库配置,生成对应的Transit实例,并且运行所有实例
List<Transit> list=database.queryList(Transit.class); for(Transit transit:list){ transit.stop(); }不断轮询数据库,一旦数据库配置表发生变更,则启动或者停止对应的Transit实例
while(isRunning){ ... list.add(/*新添加的Transit*/); ... for(Transit transit:list){ if(/*如果transit在数据库中被删除*/){ //停止transit,并在list中删除transit transit.stop(); }else if(/*如果transit在数据库中被修改*/){ //重启transit transit.reboot(); } } }
2. 服务运行管理的抽象
以上即为转发服务的运行流程,从中可以发现服务的运行流程与服务具体的运行内容可以完全脱离开来,无论是转发服务、接收服务、x服务、y服务,运行流程都是读取配置,加载运行,与服务的具体业务完全无关。
配置的动态加载实际上可以抽象为配置的监听,通过监听配置的变化来实现服务的动态加载
DatabaseListener listener=new DatabaseListener(){ public void add(Transit transit){ transit.start(); } public void delete(Transit transit){ transit.stop(); } public void modified(Transit oldTransit,Transit newTransit){ oldTransit.stop(); newTransit.start(); } }; DatabaseWatcher watcher =new DatabaseWatcher(database,Transit.class,listener); watcher.start();//监听器第一次启动时,对于数据库已经存在的数据,视作刚刚添加,全部调用add(Transit)
根据服务的抽象,可以确定服务都有以下功能
public abstract class Service{
private int id;//服务的唯一主键
private STATE state;//服务的运行状态
private COMMAND command;//服务的控制命令,通过修改数据库服务配置的command能实现服务的控制
public abstract void start();//每个服务都应当能启动
public abstract void stop();//个服务都应当能停止
}
每个服务都应当有一个管理器ServiceManager
public class ServiceManager<T>{
private Class<T> clazz;
private DatabaseWatcher watcher;
public void start(){
watcher=new DatabaseWatcher(clazz,new ServiceListener());
watcher.start();
}
public void stop(){
if(watcher!=null)
watcher.close();
}
}
其中ServiceListener为
public class ServiceListener <T extends Service> implements DatabaseListener<T> {
public void added(T t){//数据库里面增加了一个服务
t.start();
}
public void deleted(T t){//数据库里面删除了一个服务
t.stop();
}
public void modified(T oldService,T newService){//数据库里面修改了一个服务
oldService.stop();
newService.start();
}
}
3. 框架与项目的关系
数据转发服务为一个项目,下面运行多个转发器;管控服务为一个项目,下面运行多个管控监听服务;MODBUS服务为一个项目,下面运行多个MODBUS仪表监听服务。
因此项目与服务的关系实际上是一个
ServiceManager对应多个Service。
此外,整个框架下面具有多个项目,框架动态加载项目实际上跟项目动态加载服务是一样的,故也为一个ServiceManager对应多个Service。
故框架体系为:
![]()
一个frame下面有着一个ServiceManager,管理着多个Project项目。每个Project下面有一个ServiceManager,管理着多个Service服务
4. 框架运行流程
- core包下的Main类的main函数为入口函数
public class Main{
public static void main(String[] args) throws Exception {
//加载框架XML配置,构造Frame实例
Frame frame = Frame.getSingleFrame();
frame.start();
}
}
- Frame为框架,包含一个项目管理器,框架运行后开始动态加载各个Project项目
public class Frame{
private ServiceManager<Project> manager;
public void start(){
manager.start();
}
public void stop(){
manager.stop();
}
}
- Project为项目,包含自己服务管理器,项目运行后开始动态加载自己的服务
public class Project<T> extends Service{
private ServiceManager<T> manager;
public void start(){
manager.start();
}
public void stop(){
manager.stop();
}
}
例如数据转发服务主类是
Transit.class,生成的Project实例如下:public class Project<Transit> extends Service{ private ServiceManager<Transit> manager; public void start(){ //manager会监听Transit对应的数据库,动态加载Transit服务 manager.start(); } public void stop(){ manager.stop(); } }
5. 框架提供的API
框架提供的API均在Context类下
public class Context{
//提供日志
public static ILogger logger();
//提供数据库连接池
public static IDatabasePool databasePool();
//提供线程池
public static Executor executor();
//提供Tcp通讯池
public static TcpFactory tcpFactory();
//提供公用Tcp通讯池
public static TcpFactory frameTcpFactory();
}
服务可以直接调用这个API来获取资源,简化代码编写
本文详细阐述了xframe框架的服务加载流程,包括数据转发服务的运行加载步骤,服务运行管理的抽象,框架与项目的关系,以及框架的运行流程。通过监听配置变化实现服务动态加载,每个服务都有独立的管理器。框架由Main类作为入口,动态加载Project项目,每个项目管理自己的服务。Context类提供API供服务调用以获取资源。
3286

被折叠的 条评论
为什么被折叠?



