前言
程式開發畢竟還不是搬磚這種無腦體力勞動,需要事先有標準,有架構,有設計,絕對不是新公司今天創立,明天就可以開始編碼的。其實很多公司在起步的時候沒有財力和資源建設獨立的基礎架構或平臺架構部門,甚至運維團隊都沒有,但是這不妨礙我們心中有一個藍圖知道努力的方向,本文我們就簡單聊聊平臺架構相關的工作內容(或者說作為一個技術管理,應該去梳理、統一、明確的部分)的藍圖。由於本文覆蓋的內容比較多,只能拋磚引玉大概提一些,無法一一展開太詳細的東西。圖中的數字是我認為的優先順序,僅供參考。
規範
規範它雖然不是一個實際的程式碼或元件,只是一個文件,但是我覺得非常重要。沒有規範,那麼員工加下去任何一行新程式碼可能都是錯的,整個研發流程也可能會因為沒有規範導致很多不必要的事故產生。
- 程式碼提交&分支管理規範,我們可以在gitflow基礎上根據實際情況(結合運維流程,專案複雜度,團隊人數,釋出週期)進行細化,涉及到:
- 有哪幾個常駐分支,哪幾個臨時分支?
- 分支命名規範?
- 提交程式碼描述規範?
- 分支遷出和合並的時機?
- 哪些分支普通開發沒有許可權直接提交?
- 測試用什麼分支,上線又用什麼分支?
- 多版本並行開發如何提測?
- Hotfix如何處理分支?
- 編碼規範,比如Java程式碼可以以阿里Java開發手冊為基礎,大家一起過一遍,針對專案的實際情況(時間要求,對效能要求),選擇其中的一些堅決執行,然後補充一些其它的。我們也可以讓大家的IDE使用(匯入)統一的Code Style Template來要求一致的編碼格式。因為Code Style的不一致導致提交的時候大範圍的程式碼新增刪除完全會汙染提交,讓大家很難看出提交的程式碼到底改了什麼。
- 資料庫設計規範。阿里Java開發手冊裡包含了一小部分資料庫設計規範,術業有專攻,這個還是應該請資深DBA來給出一定的規範,包括但不限於:
- 命名(表和欄位字首字尾命名,外來鍵欄位命名、通用欄位命名統一)規範
- 欄位設計型別規範
- 欄位冗餘規範
- 通用欄位規範
- 索引使用規範
- ……。可以參考《朱曄的網際網路架構實踐心得S2E1:業務程式碼究竟難不難寫?》中提到的一些內容
- 專案結構規範,對於Java Maven專案來說基本目錄結構比較統一,對於其它語言的專案(比如Python),目錄結構沒有一定標準的話,專案原始碼結構會千奇百怪,最好還是對於專案結構有一個規範,包括:
- 三層結構目錄劃分
- 多環境(Profile)配置檔案
- 服務介面、服務實現、Web、Job模組命名
- 最後是專案管理流程,有一些公司會有專門的PMO,有一些初創公司研發Leader也會充當PMO的角色,雖然這個活一般和平臺架構沒啥關係,不管怎麼樣,既然是專案肯定少不了專案管理,作為技術管理角色需要關注的一個點,專案管理流程也是比較重要的:
- 迭代週期,迭代週期中的大環節大概發生的時間點
- 開哪些會,開會時間點是?(日站會、周例會、啟動會、回顧會、覆盤會、排期會、PRD預評審會、PRD評審會、測試用例評審會、上線方案討論會)
- 專案生命週期中每一個角色產出哪些文件?
- 任務在哪裡管理,每一個角色怎麼去維護任務狀態的流轉?不可能任務的每一個狀態的流轉都由PMO來做
基礎框架
使用一些基礎框架來做應用開發是必須的,對於Java技術棧,大家所熟悉的框架有Spring Cloud全家桶、Spring Boot套件(封裝的各種starters)、Mybatis等,直接使用這些框架進行開發是可以的,但是更建議的是由基礎架構團隊封裝自己的框架,自己做一層封裝,我們可以以類似Spring Boot Starter的模式,為所有的元件封裝自己的Starter模組,好處是:
- 方便進行統一的外部依賴類庫 & 庫版本管理和約定
- 方便針對公司內部情況做更合適的自動配置(甚至實現0配置)
- 如果內部技術棧是異構的話,使用統一的框架有助於技術棧後端基礎設施的打通
- 為所有的模組打通監控,自動配置AOP做相應的攔截統一抓取獲取監控資料
- 模組之間可以相互整合和配合,實現1+1>2的效果
- 還有很重要的一點是,我們可以提供相應的管控後臺來配合框架使用,把框架的配置、管理和審計暴露在控制檯上
其實說白了,就是使用自己封裝的類庫佔坑,哪怕只是一層淺淺的封裝,也是很有好處的,不僅僅是做了各種統一(使用框架的統一,框架版本號的統一),更多的是因為佔了坑(當然,要擴充套件做Java agent動態位元組碼注入的方式也是可行的,這種方式的缺點是沒有辦法提供API給業務使用),以後直接可以通過升級框架通過IOC元件替換+AOP直接做各種擴充套件(不需要再麻煩業務團隊了)。
我們來看看這裡腦圖上大概列出的一些業務開發需要用到的常見模組(可以看一下我們公司開源的框架https://github.com/ke-finance/summerframework ,當然開源出來的模組比較少,實際內部封裝了這裡提到的所有模組):
- Web MVC:可以基於Spring MVC進行封裝,增加一些模板引擎的支援等
- 資料訪問:可以基於MyBatis或Mybatis Plus+Druid資料來源進行封裝,做一些額外的功能,比如敏感資料加密儲存
- RPC服務呼叫或微服務:可以基於Dubbo或Spring Cloud(Feign+Eureka)進行封裝,在客戶端方面擴充套件一些更智慧的LB演算法,以及路由策略(比如灰度)等功能
- Web API:可以在Spring MVC+Swagger UI基礎上實現功能,提供統一的RESTful服務端API的標準,比如規範化API版本、響應結構體自動包裝(自適應)、錯誤包裝、HATEOAS超媒體資源導航整合、資料加解密實現、Collection資源的規範化、自動的mock介面的實現等
- 配置:可以基於攜程Apollo(https://github.com/ctripcorp/apollo )客戶端進行封裝,做自動配置
- 訊息:可以封裝RabbitMQ、RocketMQ的客戶端實現統一的訊息API,然後擴充套件事務訊息(收發訊息和業務邏輯本地事務在一個事務中處理)等功能
- 快取:可以基於CacheCloud(https://github.com/sohutv/cachecloud )提供Redis快取服務
- 排程:可以封裝XXLJob(https://github.com/xuxueli/xxl-job/ )或ElasticJob(http://elasticjob.io)提供排程服務
- 日誌監控:可以基於Micrometer實現應用打點,找一個APM(Skywalking https://github.com/apache/skywalking 或Pinpoint https://github.com/naver/pinpoint )整合trace功能,擴充套件logback做日誌脫敏,擴充套件Spring Boot Actuator Endpoint等功能
- 鎖:可以基於Redisson封裝分散式鎖,使用統一的API來提供記憶體鎖和分散式鎖
- 分散式事務:主要是兩塊,同步2PC分散式事務處理(比如我們開源的https://github.com/ke-finance/dts ),非同步的saga思想的實現,參考https://github.com/eventuate-tram/eventuate-tram-sagas 。
- 彈性:流控+隔離+熔斷,考慮基於https://github.com/alibaba/Sentinel 來實現,可以是獨立的模組提供服務,也可以整合到Web API或RPC模組中去
- 安全:可以基於Spring Security進行擴充套件,加入符合業務需求的風控策略進去
基礎平臺
基礎平臺(管理平臺)需要和基礎框架打配合,框架是開發的時候使用的,平臺更多的是開發或運維人員做技術運營時使用的。很多開源框架都已經提供了管理後臺,我們需要做的可能只是一些小修改,比如包括:
- 打通公司內部自己的賬號登入體系和許可權體系
- 根據不同的環境(開發、測試、灰度、生產)部署多份管理控制檯
- 根據需要看是否需要做多租戶的改造,實現業務隔離
有些平臺是重流程的,這些可能需要自主開發,大概介紹一下腦圖上提到的這些:
- 配置平臺:如果使用了攜程Apollo,自然就是使用Apollo的管理後臺
- 微服務管理平臺:這裡我列出了兩個方面的工作,一個是服務中心,更多的是服務維護、管理、監控方面的功能,可以基於Spring Cloud Admin進行改造;一個是服務集市,更多的是服務標準化方面的管理,比如服務上線需要的文件,接入的監控系統,以及上線後統一的文件中心,服務集市類似於App Store的概念
- 快取平臺,如果使用了CacheCloud,可以使用CacheCloud的管理後臺
- 日誌平臺,分為兩塊,一塊是日誌收集展示基本ELK已經是標準;還有一塊是日誌異常報警,可以自己來開發,基於Kafka消費日誌非同步做日誌篩選+聚合結合自己公司的IM和郵件體系做報警
- 資料庫管理平臺:
- DDL/DML工作流:開發提交申請,主管審批,自動執行,外加自動的風險檢測,優化建議等
- DDL/DML變更通知:方便大資料以及運營團隊針對感興趣的資料庫和表進行訂閱,在DDL應用到各個環境(測試、生產)的時候能夠第一時間得到通知可以進行人工、自動處理(類似before,after Filter的概念)
- 資料庫知識庫:有一個統一的地方檢視資料庫的結構說明、字典列舉的定義
- 當然資料庫管理平臺還可以進一步做資料庫監控、慢SQL優化原因分析等功能
- 全鏈路追蹤平臺:比如如果使用Skywalking的話可以實現它提供的管理臺,主要功能無非是依賴拓撲分析、Trace檢視、服務效能分析等
- 指標檢視平臺:分為兩塊,Dashboard一般可以考慮直接使用Grafana,報警的話雖然Grafana也有Alert但是還是建議在更底層(資料來源頭)去做,可以基於流處理去做或基於定時拉的方式去實現
基礎中介軟體
中介軟體是指獨立部署的不具有業務邏輯耦合 的通用服務,儲存服務在廣義上歸到中介軟體也不是不可以,這裡大概列了幾個典型:
- MQ代理(Broker,不是Proxy),比如RabbitMQ、RocketMQ、Kafka
- API閘道器,有很多開源的閘道器實現,比如Kong(https://github.com/Kong/kong )、Spring Cloud Gateway,我們也實現了一套https://github.com/ke-finance/tesla ,一般閘道器的主要功能是呼叫路由、協議轉換、呼叫編排,然後也會以外掛和過濾器形式提供很多安全、彈性方面的擴充套件功能
- DB代理,比如類似https://github.com/flike/kingshard 和https://github.com/Qihoo360/Atlas 的MySQL Proxy,實現資料庫的讀寫分離、分表分庫、故障轉移、彈性處理、監控、SQL優化等功能
- ES叢集,也可以理解為中介軟體,畢竟ES其實做的就是基於Lucene的分散式叢集管理工作
這些中介軟體雖然很多時候做的是Proxy背後的其它服務,但是節點本身很可能是有狀態的,也需要考慮中介軟體本身的高可用性問題。
基礎服務
一般而言如果公司具有多個專案的話,專案之間肯定會用到一些通用的內部和外部能力,這些能力和業務邏輯沒有太多關係,可以考慮把這些能力進行統一的封裝獨立部署以微服務形式提供出來,這樣所有專案都可以快速對接。
在這裡把基礎服務分為了兩類,一類是沒有業務邏輯的純基礎服務,往往是對接封裝一個或多個外部服務通道,另外一類是包含一些業務的業務基礎服務。對於第一類基礎服務你可能會想,既然是對接外部服務通道直接使用他們的SDK或服務是不是直接在業務系統使用那些三方SDK就好了,基礎服務是需要做什麼呢?我覺得基礎服務應該這麼封裝:
- 封裝外部服務的SDK,一般而言比如簡訊也好、推送也好、儲存也好,都會使用多家提供的服務做備份、降級,通過我們的SDK提供統一的對內API,遮蔽不同SDK的API差異
- 提供一個服務端,在服務端做資料落地,落地的目的有幾個:
- 方便和外部進行服務消費對賬
- 方便出錯的時候查詢原因
- 方便和外部服務同步呼叫狀態(比如簡訊到達)
- 方便進行服務餘額預警
- 服務端除了做資料落地,由統一的服務端做出口的好處是:
- 做許可權控制,一般而言即使是公司內部的專案進行基礎服務的呼叫應該也是需要先申請再使用的,甚至需要做服務呼叫量的控制(類似在內部再實現一層SaaS)
- 收斂呼叫源IP
- 集中管理呼叫外部SaaS服務的金鑰
- 外部服務的降級和切換策略更換比較方便
- 給接入方做報警
- 做一個管理後臺,雖然外部服務提供方作為SaaS產品一般都會有不錯的控制檯(其實更多的時候,不可能把外部服務的控制檯的許可權放給所有人看,內部業務方看自己的基礎服務控制檯即可),但是我們內部做一個管理後臺意義還是很大的,主要的功能一般是:
- 統一登入
- 賬號(包括Secret)申請和分配,以及配額、限流等配置(管理員許可權)
- 呼叫記錄(請求、結果)檢視
- 呼叫模板的配置(考慮一下是不是放開服務的使用,比如簡訊、郵件、推送一般是基於模板的,模板需要內部外部稽核後才能使用)
如果每一個服務都有控制檯的話,可以大大方便業務方的自主接入和問題排查,這是基礎服務封裝非常有價值的一個點,對於大點的公司內部專案眾多就更需要把基礎服務在內部進行SaaS化了,而且最好對於不同的基礎服務打通接入方(統一的地方來申請所有需要的基礎服務)。
這裡腦圖上大概列了一些常見的基礎服務和業務服務,每一個公司根據自己的業務一般都會不盡相同,基礎服務包括:
- 簡訊:接入多個簡訊渠道,根據政策、費率、到達率等情況路由
- 檔案儲存:接入多個小檔案儲存服務(比如七牛、騰訊雲),根據儲存服務提供的功能,檔案大小、費率等情況路由
- 郵件:接入內部和外部(比如SendCloud)的郵件服務,根據使用場景進行路由
- 推送:接入多個推送渠道(比如極光、個推),並且做使用者、裝置的關係維護
- 唯一ID:全域性唯一ID的生成
- 圖形、滑動、點選、智慧驗證碼:提供統一的驗證碼服務,可以根據場景自動選擇驗證碼型別
- 電子簽章:接入多個電子簽章服務,根據費率等因素路由
- 地圖服務:接入多個外部地圖服務,根據功能以及接入方使用的地圖進行服務選擇
業務服務包括:
- RBAC許可權控制:統一的RBAC配置後臺,以及方便的SDK
- 通用表單服務:根據後臺配置的表單自動生成介面,以及表單資訊的收集
- 狀態機:可以借鑑https://github.com/hekailiang/squirrel ,基於狀態(State)、行為(Action)、轉移(Transition)、條件(Condition)等概念,構建基於資料庫的狀態機平臺
- 統一支付:聚合支付,業務方可以快速接入多種支付渠道,並且統一支付可以提供統一的SDK和H5來實現統一的支付收銀臺
- 工作流、爬蟲、SSO……不詳細說明了
工程效率
接下去也簡單提一下工程效率和運維範疇的事情,雖然這和平臺架構沒啥太大關係,但是這兩塊是很重要的技術基建工作:
- 原始碼倉庫:比如可以選擇Gitlab或atlassian三件套的Bitbucket
- 內部類庫倉庫:比如Java的Maven倉庫,可以自己搭建Nexus倉庫
- 專案管理平臺:可以選擇SaaS產品(比如Tower、Teambition),比較有名的是atlassian三件套的Jira
- 知識管理平臺:可以選擇SaaS或開源Wiki產品,比較有名的是atlassian三件套的Confluence
- Bug管理平臺:比如可以選擇禪道或直接複用Jira
- 程式碼質量分析:比如可以搭建SonarQube平臺
運維
這裡提到的一些運維繫統相關工作有的公司是架構團隊來建設的,列一個大概:
- CI/CD平臺:一般而言需要自己結合公司的工作流程做一套CI/CD平臺(底層可以基於Jenkins(或直接SSH+指令碼)封裝),這個平臺需要結合公司的工作流程去做,比如誰可以發起流程,每一個釋出環節需要誰來審批,釋出時間視窗等等
- DNS平臺:一般會直接使用域名管理商的平臺或類似DNSPod這種平臺
- CMDB:一般都會根據自己的情況自建平臺,進行運維各個層次相關資源的後設資料以及配置管理
- 監控:一般會基於Prometheus+Grafana+Zabbix等開源專案來打造運維的基礎監控
- CDN平臺:一般是用雲的,比如七牛、又拍或三大雲服務的CDN都可以
- 叢集配置管理:這個不是指CMDB,是指批量進行叢集配置應用操作,管理操作的平臺,比如Chef、Puppet、Ansible、Fabric,一般也是基於開源改造封裝或直接用開源的
- 容器編排:比如K8S平臺,一般可能會基於k8s的API做一套自己的k8s管控平臺或選用類似Rancher這種更好用更高層的服務,完全基於命令列的k8s運維不是很高效易用
- 容器映象倉庫:比如Docker私有倉庫Harbor
總結
好吧,的確一些中大型網際網路公司是有超過100個內部系統是和研發相關的,甚至需要有專門的導航網站來管理工程效率、運維、基礎框架、基礎服務、基礎中介軟體、基礎平臺的這些網站,這些系統本身的維護工作量也是不小的,一整理就會發現原來除了業務程式還有這麼多周邊的東西是為研發服務的,歡迎大家針對本文的內容進行補充。