2019独角兽企业重金招聘Python工程师标准>>>
为了大家比较快速的开发微服务,规范dubbo,spring,mybatis,hessian,netty的版本和用法,我写了一个demo,下面对demo的功能做个简单的介绍,如有疑问的地方,可以私下问我。
微服务项目示例 整合了dubbo2.5.11+spring 4.3.10+mybatis3.4.6+sharding-jdbc1.5.4.1(分库分表客户端)+apollo(集中配置) 包括微服务的rpc调用,数据库的增删改查,分布式集群唯一命名,分布式id生成,数据分布算法(hash一致性+pre-shard)
快速入门
下载源码
源码你可以从url获取:https://github.com/HowardYi/MicroServiceDemo ;
里面有一个spring-sharding-jdbc-example-mybatis-oracle子项目,大家导入maven项目即可
准备环境
注意能访问到apollo 服务地址,oracle服务地址,zk服务地址,地址信息在配置文件中。需要自己打通这些服务依赖。
运行测试
MainProvider.java可以测试分库分表下的增删改查,主键和非主键路由算法测试,hint方式路由测试,分页排序功能测试,多表并发查询结果归并测试。 启动后提供dubbo服务,供下面MainProviderGateway.java应用调用,dubbo协议可调整。
MainProviderGateway.java启动后提供模拟的服务网关,对服务接口的封装,同时对外提供rest接口服务,swagger api定义,方便客户端在swagger ui上面进行接口定义查看,接口在线测试。
MainConsumer.java启动后,调用上面MainProviderGateway的接口,可以测试dubbo远程调用,rest协议方式。
DistributionInstanceNoAllocator.java测试集群唯一编号生成功能。
DefaultIdGeneratorImpl.java测试雪花算法id生成功能。
ConsistedHashRouter.java测试一致性hash算法数据分布功能。
整体结构
依赖包结构
maven作为项目管理,提供编译,打包,组装发布的目录结构等功能;
dubbo2.5.11作为微服务框架,提供服务rpc,软负载均衡,容错重试,服务自动发现和注册,服务性能监控,服务可用性监测,后台管理的服务依赖,动态路由设置,动态参数调整,ip鉴权等功能,目前被dubbo_integration间接依赖进来,包括web容器启动dubbo支持,restful风格的接口swagger 功能支持,http/hessian3/hessian等协议的附件功能支持等;
spring 4.3.11作为业务逻辑层框架,提供ioc,aop容器,事务,配置等功能;
mybatis3.4.6+spring-mybatis1.3.2+pagehelper5作为持久层框架,提供dao自动生成,注解方式sql写法,分页排序支持等;
apollo0.10提供参数配置功能,不同环境的参数配置,不再需要maven的fliter功能,打不同的部署包;
dbcp+ojdbc6提供数据源连接池和驱动;
slf4j+logback提供日志输出功能;
sharding-jdbc作为关系型数据的分布式客户端框架,提供hint方式和算法方式的路由,并发查询,结果排序分页统计;此功能在大部分项目可以忽略;
curator2.7.1作为访问zookeeper客户端;
代码结构
com.yspay.common.cluster应用实例机器唯一编号生成,动态生成唯一标识;
com.yspay.common.coordinator分布式协调器客户端,封装访问zk的代码;
com.yspay.common.datasource支持加密用户名和密码的数据源连接池;
com.yspay.common.idgenerator snowflake雪花算法作为唯一id生成器,取代oracle自增序列;
com.yspay.common.shard.consistedhash 一致性hash算法路由表,分库分表的算法;
com.yspay.sample.dubboprovider.api 应用服务对外的接口层;
com.yspay.sample.dubboprovider.datasource数据源层,分布式的数据源连接池;
com.yspay.sample.dubboprovider.entity业务实体层;
com.yspay.sample.dubboprovider.repository数据库持久层;
com.yspay.sample.dubboprovider.service业务逻辑层;
常用功能用法开发指南
dubbo服务
配置
1,配置加载容器,应用信息,协议和日志等src\main\resources\dubbo.properties:
dubbo.container-》dubbo应用main方法启动时候加载哪些容器,目前配置有:spring,spring上下文加载,jetty,dubbo服务状态对外展示的web容器启动,logback,dubbo服务的日志组件初始化;
dubbo.application-》dubbo应用信息,管理控制台可以看到服务提供者信息;
dubbo.logback-》logback日志配置;
dubbo.protocol-》dubbo rpc协议配置,规定了通信传输组件netty4,对象序列化方式hessian2,对外服务的ip(当有多个ip地址时需要指定)和端口,处理业务的工作线程池模型和数量,最大可连接客户端的数量;
jvm.heapdump.path-》jvm内存溢出时,堆栈导出目录
2,配置注册中心和性能监控src\main\resources\META-INF\spring\dubboCommonContext.xml:
编写dubbo服务代码和向注册中心注册服务
你可以编写一个spring bean (api层服务),然后加上下面简单配置即可:
配置文件src\main\resources\META-INF\spring\dubboProviderContext.xml
发布服务可以指定协议,指定注册中心等信息,具体细节参考dubbo开发指南。
从注册中心发现服务和引用远程服务
引入服务端发布的服务接口依赖包,然后加上下面配置即可:
src\main\resources\META-INF\spring\dubboConsumerContext.xml
然后客户端代码就可以注入这个bean,调用远程服务了。
集中配置apollo指南
1,配置应用唯一标识,属性文件:src\main\resources\META-INF\app.properties
app.id-》指定应用在apollo配置中心的唯一标识,可以和dubbo应用名称一致
2,配置spring从配置中心加载哪些配置 src/main/resources/META-INF/spring/apolloContext.xml:
apollo以namespace为配置的最小集合单位,namespace包括一组配置(key=value形式配置单元),具体概念参考apollo官方用法
3,应用启动时指定当前环境:
jvm系统参数需要包括-Denv=dev或fat或uat或pro,指定当前运行环境,应用程序启动后根据这个值去集中配置服务取相关配置;
shell启动脚本会从操作系统环境变量获取这个evn参数,然后传递给jvm系统参数;
如果你运行Main进行测试,代码里面通过编码方式指定env:
// 设置环境变量env,apollo(集中配置)需要此变量
String env = System.getProperty("env");
if (env == null) {
System.setProperty("env", "FAT");
}
4,引用配置中心的参数值
下面是数据源的地址参数,不同环境值不同,使用${name:defaultvalue}方式
5,保证apollo配置文件本地备份目录有读写权限
apollo会在本地保存一份配置文件,防止不能访问远程配置服务的时候使用本地配置,默认会在/opt/data目录下,如果是windows是在c盘下这个目录;
业务逻辑层事务控制
1,配置事务管理器,以及注解方式事务管理:
src\main\resources\META-INF\spring\serviceContext.xml
2,代码中标注注解:
只读事务:
@Override
@Transactional(readOnly = true)
public void select() {
}
写事务,指示方法事务传播属性,根据异常类型回滚事务:
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public void insert() {
}
持久层mybatis开发
1,配置
src\main\resources\META-INF\spring\mybatisContext.xml
配置mybatis session factory跟hibernate类似,这里面有一个pageInterceptor插件,用来生成分页sql的,具体用法可以参考pagehelper官网。
helperDialect=oracle
rowBoundsWithCount=true
这个是配置自动生成dao(mybatis叫mapper)的实现类的,在basePackage下面的所有mapper接口,都会自动生成一个实现类bean,开发者不需要自己写dao的实现类,只需要定义dao接口以及dao接口需要使用的sql即可
2,自动生成dao(mapper)代码和entity代码
2.1安装mybatis generator eclipse插件,
2.2编写代码自动生成工具需要的配置,主要是指定数据源,生成代码的目录,哪些表需要生成代码等等,项目中有一个配置文件例子:src\mybatis-generator-config\generatorConfig.xml,
2.3在eclipse里面,点击配置文件,右键菜单-》Run-》mybatis generator即可生成代码了
3, 编写定制的dao方法
上面自动生成的mapper方法通常不够满足自己的需求,定制mapper是必要的。
创建新mapper接口,一般不要再原来自动生成的mapper上进行修改,不然表改动后,重新生成mapper代码,会把你写的方法抹掉;我习惯在原来表mapper类的名字后加Ext代表是扩展的mapper。
类com\yspay\sample\dubboprovider\repository\OrderMapperExt.java,定义为自动生成类OrderMapper.java的扩展:
更新写法:
@Update({ "update T_ORDER ", "set STATUS = #{status,jdbcType=VARCHAR} ",
"where USER_ID = #{userId,jdbcType=VARCHAR} and ORDER_ID = #{orderId,jdbcType=VARCHAR}" })
int updateStatusByUserIdOrderId(Order record);
分页写法:
@Select({ "select", "ORDER_ID, USER_ID, STATUS, CREATE_DATE",
"from T_ORDER" })
@ResultMap("OrderMap")
List
只要方法里面有RowBounds参数,sql会自动再加上分页的sql(rownum>? and rownum);所以上面查询sql并不需要分页相关的sql