文档章节

dubbo+apollo微服务开发指南

PageYi
 PageYi
发布于 10/23 15:12
字数 2538
阅读 68
收藏 4

为了大家比较快速的开发微服务,规范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:registry protocol="zookeeper" client="curator" address="${dubbo.registry.address:10.213.32.120:2181}" />

<!--监控,测试环境和生产环境的时候打开-->
<dubbo:monitor protocol="registry"/>
 

编写dubbo服务代码和向注册中心注册服务

你可以编写一个spring bean (api层服务),然后加上下面简单配置即可:

配置文件src\main\resources\META-INF\spring\dubboProviderContext.xml

<dubbo:service interface="com.yspay.sample.dubboprovider.api.IOrderServiceApi" ref="orderServiceApiImpl"
protocol="dubbo" validation="false"></dubbo:service>

发布服务可以指定协议,指定注册中心等信息,具体细节参考dubbo开发指南。

 

从注册中心发现服务和引用远程服务

引入服务端发布的服务接口依赖包,然后加上下面配置即可:

src\main\resources\META-INF\spring\dubboConsumerContext.xml

<dubbo:reference id="orderServiceApiClient" interface="com.yspay.sample.dubboprovider.api.IOrderServiceApi"></dubbo:reference>

然后客户端代码就可以注入这个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官方用法

<!-- 这个是最简单的配置形式,一般应用用这种形式就可以了,用来指示Apollo注入application namespace的配置到Spring环境中 -->
<apollo:config order="3"/>

<!-- 这个是最复杂的配置形式,指示Apollo注入PAID.dubbo namespace的配置到Spring环境中,并且顺序在application前面 -->
<apollo:config namespaces="PAID.dubbo" order="2"/>

<apollo:config namespaces="PAID.datasource" order="1"/>

 

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}方式

<bean id="ds_0" class="com.yspay.common.datasource.SecretBasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="${manager.url:jdbc:oracle:thin:@10.168.192.1:1521:orcl}"/>
<property name="username" value="${manager.username:defaultusername}"/>
<property name="password" value="${manager.password:defaultpwd}"/>
<property name="defaultAutoCommit" value="false"></property>
<property name="initialSize" value="${trade.inisize:3}"/>
<property name="maxActive" value="${trade.maxsize:10}"/>
<property name="minIdle" value="${trade.maxidle:2}" />
<property name="maxIdle" value="${trade.minidle:2}" />
<property name="validationQuery" value="select * from dual"/>
<property name="testWhileIdle" value="false" />
<property name="timeBetweenEvictionRunsMillis" value="600" />
</bean>

5,保证apollo配置文件本地备份目录有读写权限

apollo会在本地保存一份配置文件,防止不能访问远程配置服务的时候使用本地配置,默认会在/opt/data目录下,如果是windows是在c盘下这个目录;

 

业务逻辑层事务控制

1,配置事务管理器,以及注解方式事务管理:

src\main\resources\META-INF\spring\serviceContext.xml

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="shardingDataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

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官网。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="shardingDataSource"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
helperDialect=oracle
rowBoundsWithCount=true
</value>
</property>
</bean>
</array>
</property>
</bean>

这个是配置自动生成dao(mybatis叫mapper)的实现类的,在basePackage下面的所有mapper接口,都会自动生成一个实现类bean,开发者不需要自己写dao的实现类,只需要定义dao接口以及dao接口需要使用的sql即可
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yspay.sample.dubboprovider.repository"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
 

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<Order> selectByPage(RowBounds row);

只要方法里面有RowBounds参数,sql会自动再加上分页的sql(rownum>? and rownum<?);所以上面查询sql并不需要分页相关的sql

 

 

© 著作权归作者所有

共有 人打赏支持
PageYi
粉丝 8
博文 15
码字总数 14044
作品 0
深圳
私信 提问
微服务指南走北(五):什么样的服务才可以说是微服务?

最近有朋友提出了问题:“是不是拥有了服务发现就是微服务了?”,对于这个问题,很难回答,毕竟微服务的定义在每个人心里都是不一样的,就像“互联网思维”一样,我们说得清“互联网”,却总...

gsying1474
2017/04/23
0
0
微服务指南走北(一):微服务是什么

微服务“Microservices”已经成为软件架构最流行的热词之一。网络上看到很多关于微服务的文章,但是感觉很多离我们还很遥远,并且没有找到多少真正在企业场景中应用的实例。此处省略一万字于...

gsying1474
2016/08/10
0
0
微服务指南走北(二):微服务架构的进程间通信(IPC)

先抛出几个问题: 微服务架构的交互模式有哪些? 微服务常用的进程间通信技术有哪些? 如何处理部分请求失败? API的定义需要注意的事项有哪些 微服务的通信机制与SOA的通信机制之间的关系与区...

gsying1474
2016/08/14
0
0
微服务指南走北(四):你不愿意做微服务架构的十个理由

近段时间离职,跟同事们讲解我之前所做的微服务相关产品,对于同事们提出的问题,做了如下整理出来,加上自己的理解,分享出来跟大家一起探讨下: 问题预览 我为什么要换微服务?能给我带来什...

gsying1474
2017/04/18
0
0
荐书丨Kubernetes权威指南——企业级容器云实战

点击上方“程序人生”,选择“置顶公众号” 第一时间关注程序猿(媛)身边的故事 《Kubernetes权威指南》作者全新力作 直击容器云技术热点和难点 Kubernetes企业级容器云落地实战及指南 在开...

CSDN程序人生
08/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

强化学习在美团“猜你喜欢”的实践

1 概述 “猜你喜欢”是美团流量最大的推荐展位,位于首页最下方,产品形态为信息流,承担了帮助用户完成意图转化、发现兴趣、并向美团点评各个业务方导流的责任。经过多年迭代,目前“猜你喜...

美团技术团队
24分钟前
1
0
docker - 常用命令

1. docker服务的启动、停止、重启 [root@localhost ~]# service docker restartRedirecting to /bin/systemctl restart docker.service[root@localhost ~]# service docker stopRedir......

细肉云吞
27分钟前
3
0
安装CentOS 6.5 系统

一、安装CentOS 6.5 系统 1、选择第一个 "Install or upgrade an existing system" 2、选择跳过 “Skip” 3、直接下一步 4、建议初学者选择中文的,工作中选择 “English” 5、键盘选择 “美...

寰宇01
39分钟前
1
0
AR+ 实时音视频通话,虚拟与现实无缝结合

今年中旬 Google 在万众期待下推出了 ARCore,能将现实与数码完美无缝地融合在一起,丰富我们的现实世界。通过它开发者可以更加快速方便地在 Android 平台开发 AR 应用,凭借 AR 技术大量产品...

七牛云
39分钟前
1
0
手把手教你实现一个 Vue 进度条组件!

最近在个人的项目中,想对页面之间跳转的过程进行优化,想到了很多文档或 npm 等都用到的页面跳转进度条,于是便想自己去实现一个,特此记录。 来看下 npm 搜索组件时候的效果: so 下面咱们...

我的卡
40分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部