o2ocrm一些经验
工具
mac环境下
- idea java开发ide
- datagrip 数据库工具
- Alfred 效率利器 (查找,保存密码等)
- iterm2 终端利器 配合zsh(git提示)
- sublime 文本编辑器
- MacDown markdown编写工具
技术网站
- http://www.infoq.com/cn/
- http://jinnianshilongnian.iteye.com/blog/1617451 可关注其 微信公共号
- http://ifeve.com/
规范
- 格式化文件 (eclipse code formatter) 统一java和xml格式
- lombok 注解生成set get log 构造 hashcode tostring等方法
- Free Mybatis plugin + 自定义mybatis gennertor
- 统一mapper接口命名规范 get get**List insert delete update
- 拥抱JDK8,lambda,尽量避免null等
- 善于利用第三方库
o2ocrm
系统目前情况
- leads量 1153124大概116w
- 平均线索量每天大约6k左右的
- 员工数 4651, 外呼团队105,服务经理3627
系统功能
业务流程以及系统交互
- 投放到不同渠道用tsid,taid标记不同的渠道和城市创业等
- 用户在渠道上填写用户手机号等生产线索
- 自动派单到外呼名下
- 外呼领取跟进,预约
- SA领取跟进
- 相关数据的报表
系统内解耦和系统间解耦
系统内
- 面向接口编程,组合等
- guava eventbus , spring 事件,设计模式
- 个人比较喜欢的模式
列子
这个是我们crmH5系统中生成线索后的一个业务处理流程
可以看到目前有 多少条件判断
- 在线销售 参数idt
- 模式哟 ts,sa, 客户经理模式
- 自约单
- 合作商户
总体来说是根据leads中的参数判断不同的模式处理不同的业务一般简单来说我们可能会if else if if 等
解决?个人比较喜欢的模式 基于spring 处理if else 等扩展性问题
- spring 注解获取接口实现的列表,@Order排序注解控制排序
- 定义各种业务处理接口
/**
* Created by iluoxuan on 16/10/19.
* 各种模式的业务处理
*/
public interface ModelHandler {
/**
* 是否支持业务
*
* @return
*/
boolean support(HandlerParam param);
void before();
/**
* 处理
*
* @param param
* @return
*/
HandlerResult handler(HandlerParam param);
/**
* 是否可以 进行去处理下一个handler
*
* @return
*/
boolean isNextHandler();
void after(HandlerParam param);
}
- 个人使用这个处理模式,基本可以解决大部分if else扩展问题
系统间解耦
- rpc
- 消息队里
- 第三方jar类库
我们目前all in one
- 共用mapper
- 公用库 邮件,http调用封装,短信
- 封装spring data redis使用,分布式锁,常用的标记等serice
自定义类库使用方式
/**
* Created by iluoxuan on 16/10/12.
*/
@Configuration
@EnableCommonBean //启用common组件
@EnableSpringRedisExt //启动redis组件
@EnableRetry //起用重试
@EnableMailService // 启用邮件
public class AppConfig {
}
异步和线程池隔离
非核心业务流程能异步就异步
- 操作日志
- 异步收集数据
- 异步调用反作弊接口
不同的业务定义不同的线程池隔离
- 不同业务数据库连接池 (一个专门处理报表)【线上因为报表查询太慢导致druid连接池爆满获取链接超时】
- spring 多线程池配置
<!--开启注解调度支持 @Async @Scheduled-->
<task:annotation-driven executor="taskExecutor" proxy-target-class="true"/>
<!-- 线程池 考虑Hystrix做隔离-->
<task:executor id="taskExecutor" pool-size="5-15" queue-capacity="100"/>
<!-- 收集leads反作弊信息 线程池 -->
<task:executor id="riskCollectExceutor" pool-size="5-15" queue-capacity="1000"/>
重复提交,分布式锁解决
定义分布式key就可以,解决并发同时提交多次的问题
解决部署重启会话丢失重启已经多台机器session问题
- 引入spring-session
监控
- 目前采用发邮件的形式,微信绑定邮箱
ControllerAdvice 处理不同类型的异常,未知异常,邮件报警
crmjob
已经目前解决的
任务的cron更新,重启,暂停,恢复,http接口提供,支持业务参数
待解决
- 任务监控,分布式化,任务依赖,任务分片,触发一次的功能
- 调研了elastic-job https://github.com/dangdangdotcom/elastic-job
- 目前已经有10多个任务在运行,主要是报表数据的同步,中间表数据的生成
- 只需要编辑修改时间参数 就是重新阶段同步
目前系统的问题
- 有部分重复代码在 crmh5 和crmweb的service中,不多;大部分重复的都拆到了common中
- mapper还存在xml和注解混用的,命名不规范的
- spring cache缓存失效 模糊匹配keys问题
- 和商城共用redis问题(有坑)
- crmjob分布式化,分片
- 报表开发每次都要修改sql,加字段重新同步数据问题
在业务稳定过程中我们可以思考什么
如何沉淀自己的类库
如何更好的设计可扩展性的代码
解决cache更新问题
- cannel订阅binlong,更新cache
解决量大情况下关联表查询问题
- 定义sechma走es,如果处理更新索引问题
- cannel订阅binlong,更新索引
分布式任务
- 触发一次,业务参数,分片,动态更新等