微服务的定义
一次编写,处处调用
由于之前的公司没有使用spring系列,也没有使用dubbo系列,而是公司自己弄了一套框架,有许多优点,也有一些不足,在其启发下,自己也搞了一套简化版的微服务架构
主要解决了以下问题
1.一主多从时,多个数据源进行轮询负载均衡
2.分库分表时,自动根据分库分表规则进行sql的改写,定位正确的数据源和表,进行数据操作,程序员正常写sql就行
3.一次编写,处处调用。无论是注册的sql服务,还是注册的本地java程序服务,还是远程服务器的服务,服务调用时,一视同仁,无需关注底层实现
4.大多数服务,通常是调用sql,像mybatis和hibernate,操作数据时特别麻烦,需要写很多的代码,而本框架简单至上,就像李小龙的截拳道一样,简单,直接,有效, 比hibernate和mybatis好用多了,开发效率也能提高很多
调用方式
所有服务的调用都是一样的,只需要知道服务名,传入指定的参数即可
例如:listUser,updateUserInfo等,然后顺序传入sprParam字段里面的参数即可:
Map mapReq = new HashMap<>();
mapReq.put("strAction", "listUser");
mapReq.put("age", "30");
Return ret = HandlerManager.instance.handler(mapReq);
if (ret.getCode() != 0) {
System.out.println("出错了: " + ret.getMsg());
return;
}
List
框架构成
1.sql服务
CREATE TABLE tbSql
(
lId INT(11) DEFAULT '0' PRIMARY KEY NOT NULL AUTO_INCREMENT,
strKey VARCHAR(36) NOT NULL COMMENT '编码',
strName VARCHAR(128) DEFAULT '' COMMENT '名称',
strSql VARCHAR(1024) DEFAULT '' COMMENT 'sql',
strParam VARCHAR(128) DEFAULT '' COMMENT '参数',
dtModifyTime DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
dtCreateTime DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
strTable VARCHAR(100) DEFAULT '' COMMENT '表名:属于哪个表的sql',
strResultType VARCHAR(32) DEFAULT '' COMMENT '返回值类型',
strDataSource VARCHAR(100) DEFAULT '' COMMENT '数据源',
strDataGroup VARCHAR(64) DEFAULT '' COMMENT '分库分表规则'
);
CREATE UNIQUE INDEX tbSql_strKey_uindex ON tbSql (strKey);
SELECT * FROM tbBorrower WHERE lUserId = '{}'
INSERT INTO stock.tbSql (lId, strKey, strName, strSql, strParam, dtModifyTime, dtCreateTime, strTable, strResultType, strDataSource, strDataGroup) VALUES (1, 'getUserMobile', '获取用户手机号', 'SELECT * FROM tbBorrower WHERE lUserId = 33;', 'lUserId', '2018-04-03 16:08:30', '2018-04-03 16:08:30', 'tbBorrower', 'list', 'stockDataSource', '');
JAVA代码调用形式如下:根据strKey顺序传入参数即可
DataSource.getDataSource().update("createTaskUser", strTaskName, strType, strMsg, strCondition);
字段说明
strKey :服务名称,调用者根据此获取来调用指定的sql
strResultType:返回类型,有list, map,int三种类型
strDataSource:数据源的名称
strDataGroup:分库分表规则,例如5:100:50000:lUserId,意思是5库百表,每个表里面存50000个用户的数据,分表的规则是根据lUserId来的,如果lUserId = 359000,那么它应该在359000/50000 = tbUser7表中,在7/5= dbUser1库中
数据源管理
数据源的数据也是放到数据库里面的,使用dbcp数据库连接池
CREATE TABLE tbDataSource
(
lId INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
strKey VARCHAR(36) NOT NULL COMMENT '数据源唯一标示',
strName VARCHAR(128) DEFAULT '' COMMENT '数据源名称',
strUsername VARCHAR(128) DEFAULT '' COMMENT '用户名',
strPassword VARCHAR(128) DEFAULT '' COMMENT '密码',
strUrl VARCHAR(128) DEFAULT '' COMMENT 'JDBC连接串,一主多从时,多个数据源用逗号分隔',
strDriverClassName VARCHAR(128) DEFAULT '' COMMENT '驱动名称',
strConnectionProperties VARCHAR(128) DEFAULT '' COMMENT '连接属性,格式[参数名=参数值]',
nIsolation INT(4) DEFAULT '2' COMMENT '事务隔离级别',
nInitialSize INT(8) DEFAULT '5' COMMENT '初始化的连接数',
nMaxTotal INT(8) DEFAULT '10' COMMENT '最大的连接数',
nMaxIdle INT(8) DEFAULT '10' COMMENT '最大空闲连接数',
nMinIdle INT(8) DEFAULT '10' COMMENT '最小空闲连接数',
nMaxWaitMillis INT(8) DEFAULT '10' COMMENT '从连接池获取一个连接时,最大的等待时间',
dtModifyTime DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
dtCreateTime DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
strDataGroup VARCHAR(64) DEFAULT '1' COMMENT '分库分表配置,五个库时值为5,1个库时值为1',
nState INT(4) DEFAULT '1' COMMENT '1:生效,0:失效'
);
CREATE UNIQUE INDEX tbDataSource_strKey_index ON tbDataSource (strKey);
strUrl 字段,在一主多从的情况下,可以将多个从库的url以逗号分隔,放到里面,在加载数据源时,
private Map> mapDataSource = new HashMap<>();
会将它们和strDataSource进行一对多的绑定,在sql调用时,进行轮询负载均衡
strDataGroup 字段,会在加载数据源时,对数据源的url经常处理:
read.user.mysql -->
read0.user.mysql, read1.user.mysql,read2.user.mysql ...
在调用sql服务时,会判断是否分库分表,也就是tbSql.strDataGroup字段是否为空,如果不为空,则会动态计算strDataSource,从而找到正确的数据源,获取正确的Collection,进行数据库操作
调用流程
1.根据服务名去sql服务里面匹配,如果找到了,调用sql查询,返回结果
2.如果没有找到相应的sql服务,去java代码里面找
// 注册java服务
HandlerManager.instance.regisger("insertUser", new InsertUserHandler());
HandlerManager.instance.regisger("listUserByName", new ListUserByNameHandler());
// 查找java服务
logger.info("sql 服务没有找到,开始查找注册服务");
Handler handler = this.map.get(map.get("strAction").toString());
if (handler != null) {
return handler.handler(map);
} else {
return Return.Error("服务找不到");
}
3.如果还找不到,就去查询其他服务器是否提供了改服务,进行远程调用