短信服務構建總結


又來水文了...
但感覺沒什么其他內容可寫,就將之前做的一個消息平台稍微做點總結.
簡單說說短信模塊的實現,做的東西不復雜,權當總結了~.

需求

功能需求

功能需求比較直接.
需要提供一些短信和統計功能即可:

  • 通知短信
  • 驗證碼短信
  • 語音短信
  • 發送量統計

非功能需求

主要是以下幾點

  • 穩定的發送保證:
    分為兩部分,一個是服務本身的穩定性,另一個是短信服務提供商的穩定性.
    服務本身穩定是自己需要實現的,可以通過微服務平台已經有的一些工具保證,這里不進行展開.而另一個是需要外部保證的,外部需要保證的東西永遠是脆弱的,所以不能僅僅使用一家服務商,需要使用多家.
  • 方便擴展:
    接着第一點,服務商可能會有更換的需求,需要保證能夠方便接入下架服務商.
  • 資產保護:
    短信相比郵件,微信通知等的一個不同是他花費比較高,一條的計價在3分左右,較長的短信會被拆為多條,如果不加限制進行保護很容易造成大量的資損.

技術選型

有了上面的需求之后就是選用什么技術了.
基礎的web服務就使用公司現有的即可.
對於存儲,因為涉及到發送信息和報告的記錄,量可能會很大(其實上線之后也還好,3個月不到千萬記錄),統計時可能會按照某些發送內容統計,使用MySQL之類的可能會不太靠譜,選擇使用ES.
對於安全,一定需要做手機號每日發送量和發送頻率等的限制,這個用redis可以較為輕松解決.

最后一個簡化版的架構圖如下:

實現細節

上面都是這個服務戰略上的一些東西,這里說一些戰術上的.

接入多家服務商

需要有多家服務商的接入,一家服務商可能同時供應多個短信功能.
同時同一個短信功能需要輪流調用所有提供的服務商,並在一家失敗后進行重試.
也需要支持靈活的配置,可以禁用掉一些服務商,也可以方便加入新的.
在實現上先定義了各個發送功能接口,例如:

interface NotiSmsSender {
    SmsSubmitResult sendNoti(NotiRequest request);
}  


interface VerifyCodeSmsSender {
    SmsSubmitResult sendVerifyCode(VerifyCodeRequest request);
}

對應的服務商實現不同的接口,提供不同的服務,每個對應的實現都有一個id字段,用於之后的配置.

現在有了一坨sender,接下來要定義router,用來進行請求的分發.
router內含有sender列表,配置router內的sender就可以實現服務商的下線功能了.
大致流程如下:

實際實現中使用了Akka,各個sender是一個actor,router負責監督各個sender的健康情況,此外天然獲得了超時時間的能力(底層使用了異步HttpClient,actor內部不會發生阻塞).

發送限制設置

關於手機號和ip的發送數量計數使用reidsincr配合時間戳相關的key就可以很簡單完成,這里不累述這個.

發送限制的話首先要針對不同功能,因為不同功能的使用量是截然不同的,並且也有隔離的作用,一個功能超限不能影響其他功能.

其次,發送的限制需要分層級,當達到了全局最大限制后,就算沒有超過單手機限制也不應該發出去了.
使用的層次是:
功能全局次數(次數) -> 單接入應用限制(次數/白名單/開關) -> 單手機/ip限制(次數/白名單/開關) -> 風控服務(開關)
最后次數要根據統計情況和業務更改做適當調整.

性能

這個服務很明顯是IO密集的,就沒什么計算,主要是調用各種外部服務,等IO返回.
所以對於這些各個用來做請求的線程池就可以配置稍微大一點,實際最主要的就是HTTP的連接池.但連接超時,讀取超時也不適合設置過大.
實際測試也沒多大問題,平日一天短信請求量也在幾w左右,並沒有太大的瓶頸.

其他的一些點和普通的web服務也大同小異了,沒有什么特別的技巧.
其實之前一些文章也是在構建這個服務的時候寫的,這段時間沒寫什么就當划水了,比如:
Akka實踐一些總結
ES踩坑筆記
這個服務構建的時候根據需要用了些之前沒有使用的組件,也算額外獲得了一些回報吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM