o2ocrm一些經(jīng)驗(yàn)
工具
mac環(huán)境下
- idea java開(kāi)發(fā)ide
- datagrip 數(shù)據(jù)庫(kù)工具
- Alfred 效率利器 (查找两波,保存密碼等)
- iterm2 終端利器 配合zsh(git提示)
- sublime 文本編輯器
- MacDown markdown編寫(xiě)工具
技術(shù)網(wǎng)站
- http://www.infoq.com/cn/
- http://jinnianshilongnian.iteye.com/blog/1617451 可關(guān)注其 微信公共號(hào)
- http://ifeve.com/
規(guī)范
- 格式化文件 (eclipse code formatter) 統(tǒng)一java和xml格式
- lombok 注解生成set get log 構(gòu)造 hashcode tostring等方法
- Free Mybatis plugin + 自定義mybatis gennertor
- 統(tǒng)一mapper接口命名規(guī)范 get get**List insert delete update
- 擁抱JDK8扁远,lambda,盡量避免null等
- 善于利用第三方庫(kù)
o2ocrm
系統(tǒng)目前情況
- leads量 1153124大概116w
- 平均線(xiàn)索量每天大約6k左右的
- 員工數(shù) 4651, 外呼團(tuán)隊(duì)105,服務(wù)經(jīng)理3627
系統(tǒng)功能
業(yè)務(wù)流程以及系統(tǒng)交互
- 投放到不同渠道用tsid耕漱,taid標(biāo)記不同的渠道和城市創(chuàng)業(yè)等
- 用戶(hù)在渠道上填寫(xiě)用戶(hù)手機(jī)號(hào)等生產(chǎn)線(xiàn)索
- 自動(dòng)派單到外呼名下
- 外呼領(lǐng)取跟進(jìn),預(yù)約
- SA領(lǐng)取跟進(jìn)
- 相關(guān)數(shù)據(jù)的報(bào)表
系統(tǒng)內(nèi)解耦和系統(tǒng)間解耦
系統(tǒng)內(nèi)
- 面向接口編程,組合等
- guava eventbus 孵运, spring 事件,設(shè)計(jì)模式
- 個(gè)人比較喜歡的模式
列子
這個(gè)是我們crmH5系統(tǒng)中生成線(xiàn)索后的一個(gè)業(yè)務(wù)處理流程
可以看到目前有 多少條件判斷
- 在線(xiàn)銷(xiāo)售 參數(shù)idt
- 模式喲 ts窃祝,sa, 客戶(hù)經(jīng)理模式
- 自約單
- 合作商戶(hù)
總體來(lái)說(shuō)是根據(jù)leads中的參數(shù)判斷不同的模式處理不同的業(yè)務(wù)一般簡(jiǎn)單來(lái)說(shuō)我們可能會(huì)if else if if 等
解決掐松?個(gè)人比較喜歡的模式 基于spring 處理if else 等擴(kuò)展性問(wèn)題
- spring 注解獲取接口實(shí)現(xiàn)的列表,@Order排序注解控制排序
- 定義各種業(yè)務(wù)處理接口
/**
* Created by iluoxuan on 16/10/19.
* 各種模式的業(yè)務(wù)處理
*/
public interface ModelHandler {
/**
* 是否支持業(yè)務(wù)
*
* @return
*/
boolean support(HandlerParam param);
void before();
/**
* 處理
*
* @param param
* @return
*/
HandlerResult handler(HandlerParam param);
/**
* 是否可以 進(jìn)行去處理下一個(gè)handler
*
* @return
*/
boolean isNextHandler();
void after(HandlerParam param);
}
- 個(gè)人使用這個(gè)處理模式粪小,基本可以解決大部分if else擴(kuò)展問(wèn)題
系統(tǒng)間解耦
- rpc
- 消息隊(duì)里
- 第三方j(luò)ar類(lèi)庫(kù)
我們目前all in one
- 共用mapper
- 公用庫(kù) 郵件大磺,http調(diào)用封裝,短信
- 封裝spring data redis使用探膊,分布式鎖杠愧,常用的標(biāo)記等serice
自定義類(lèi)庫(kù)使用方式
/**
* Created by iluoxuan on 16/10/12.
*/
@Configuration
@EnableCommonBean //啟用common組件
@EnableSpringRedisExt //啟動(dòng)redis組件
@EnableRetry //起用重試
@EnableMailService // 啟用郵件
public class AppConfig {
}
異步和線(xiàn)程池隔離
非核心業(yè)務(wù)流程能異步就異步
- 操作日志
- 異步收集數(shù)據(jù)
- 異步調(diào)用反作弊接口
不同的業(yè)務(wù)定義不同的線(xiàn)程池隔離
- 不同業(yè)務(wù)數(shù)據(jù)庫(kù)連接池 (一個(gè)專(zhuān)門(mén)處理報(bào)表)【線(xiàn)上因?yàn)閳?bào)表查詢(xún)太慢導(dǎo)致druid連接池爆滿(mǎn)獲取鏈接超時(shí)】
- spring 多線(xiàn)程池配置
<!--開(kāi)啟注解調(diào)度支持 @Async @Scheduled-->
<task:annotation-driven executor="taskExecutor" proxy-target-class="true"/>
<!-- 線(xiàn)程池 考慮Hystrix做隔離-->
<task:executor id="taskExecutor" pool-size="5-15" queue-capacity="100"/>
<!-- 收集leads反作弊信息 線(xiàn)程池 -->
<task:executor id="riskCollectExceutor" pool-size="5-15" queue-capacity="1000"/>
重復(fù)提交,分布式鎖解決
定義分布式key就可以逞壁,解決并發(fā)同時(shí)提交多次的問(wèn)題
解決部署重啟會(huì)話(huà)丟失重啟已經(jīng)多臺(tái)機(jī)器session問(wèn)題
- 引入spring-session
監(jiān)控
- 目前采用發(fā)郵件的形式流济,微信綁定郵箱
ControllerAdvice 處理不同類(lèi)型的異常,未知異常腌闯,郵件報(bào)警
crmjob
已經(jīng)目前解決的
任務(wù)的cron更新绳瘟,重啟,暫停姿骏,恢復(fù)糖声,http接口提供,支持業(yè)務(wù)參數(shù)
待解決
- 任務(wù)監(jiān)控,分布式化蘸泻,任務(wù)依賴(lài)琉苇,任務(wù)分片,觸發(fā)一次的功能
- 調(diào)研了elastic-job https://github.com/dangdangdotcom/elastic-job
- 目前已經(jīng)有10多個(gè)任務(wù)在運(yùn)行悦施,主要是報(bào)表數(shù)據(jù)的同步并扇,中間表數(shù)據(jù)的生成
- 只需要編輯修改時(shí)間參數(shù) 就是重新階段同步
目前系統(tǒng)的問(wèn)題
- 有部分重復(fù)代碼在 crmh5 和crmweb的service中,不多抡诞;大部分重復(fù)的都拆到了common中
- mapper還存在xml和注解混用的穷蛹,命名不規(guī)范的
- spring cache緩存失效 模糊匹配keys問(wèn)題
- 和商城共用redis問(wèn)題(有坑)
- crmjob分布式化,分片
- 報(bào)表開(kāi)發(fā)每次都要修改sql沐绒,加字段重新同步數(shù)據(jù)問(wèn)題
在業(yè)務(wù)穩(wěn)定過(guò)程中我們可以思考什么
如何沉淀自己的類(lèi)庫(kù)
如何更好的設(shè)計(jì)可擴(kuò)展性的代碼
解決cache更新問(wèn)題
- cannel訂閱binlong俩莽,更新cache
解決量大情況下關(guān)聯(lián)表查詢(xún)問(wèn)題
- 定義sechma走es,如果處理更新索引問(wèn)題
- cannel訂閱binlong乔遮,更新索引
分布式任務(wù)
- 觸發(fā)一次扮超,業(yè)務(wù)參數(shù),分片蹋肮,動(dòng)態(tài)更新等