spring boot / cloud (二十) 相同服務,發佈不一樣版本,支撐並行的業務需求

有半年多沒有更新了,按照常規劇本,應該會說項目很忙,工做很忙,沒空更新,吧啦吧啦,相關的話吧,java

可是細想一想,是真的麼?,忙到這幾個字都沒時間打麼?畢竟你們都很忙的,因此忙併非啥理由.git

那是由於啥呢?感受就只有一個理由能站得住腳了,就是由於"懶". 哈哈....spring

尬聊了一段,活躍下氣氛,下面進入正題架構

場景

在實際工做中,你們可能也都遇到過這樣的狀況 :app

一個正在更新迭代過程當中項目,會收到大量業務部門的需求,這些需求可能會來自於不一樣業務部門,或者不一樣的產品經理框架

而項目的onwer則須要接收到這些需求,對這些需求進行初步的分析和排期,可是在排期的過程當中,會有這樣一種尷尬的狀況發生.ide

好比,有兩個互不嗒噶的產品經理,針對同一功能點,提出了兩個不一樣業務改造的需求點,兩個需求點要求上線的時間很接近,可是又出於某種緣由,不能同時上線,或者產品經理根本沒法肯定上線時間,而告訴你儘快完成開發/測試,他則根據實際狀況肯定業務需求的發佈時間測試

那麼,對於這種狀況,一般會採用開分支的方式進行開發,即不一樣版本的並行需求的開發在不一樣分支上同時進行開發,那麼,團隊成員(開發/測試),則能夠同時的開展工做,有的負責A需求,有的負責B需求,互不影響url

起初開發階段的時候,一切很順利,可是等到開發完畢提測後,測試介入,系統要打入測試環境進行集成測試的時候,那麼問題就來了.spa

A版本和B版本,目前所屬在不一樣分支上,若是要同時進行集成測試,那系統應該如何部署呢?

方案

根據上述場景,其實核心問題是,在不添加多套集成測試的環境下,也能針對同一個服務的不一樣版本,同時進行測試.

咱們項目是基於spring cloud構建的,那麼解決的思路就是,在網關層根據不一樣的版本號進行判斷,從新指派網關路由的serviceId,那麼下面看相關的實現:

架構圖

輸入圖片說明
在這裏輸入圖片標題

相關實現

首先,在不一樣的分支上定義不一樣的版本號,而後將應用名稱拼接上版本號,這樣應用在註冊到eureka的時候,因爲版本號不一樣,那麼就會被認定爲是不一樣的服務

info.app.version=v1 # 其餘分支上定義其餘版本號
spring.application.name=service-a-${info.app.version}
複製代碼

其次,在zuul層添加路由攔截器,主要是抓取版本號(固然,這個版本號不必定要放在header裏面),得到zuul預先根據url根匹配的serviceId,而後拼接上版本號,讓其路由到正確的服務中,達到改變代理行爲的目的

@Component
public class VersionChangeFilter extends ZuulFilter {
    
    @Autowired
    private DiscoveryClient discoveryClient;


    @Override
    public String filterType() {
        return ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 9;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse();
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String version=request.getHeader("version");
        if(StringUtils.isNotBlank(version)){
            String serviceId=String.valueOf(ctx.get("serviceId")).concat(version).toLowerCase();
            List<String> services = discoveryClient.getServices();
            if(services.contains(serviceId)){
                ctx.set("serviceId",serviceId);
            }
        }
        return null;
    }
}
複製代碼

結束

這樣一來,在不增長任何環境資源的前提下,能夠實現不一樣版本服務的服務同時發佈.知足了並行集成測試的需求

固然,仍是那句話,解決一樣問題的方法有多種,我上述的方法也不必定是最好的,若是有更好經驗的同窗,歡迎你們踊躍討論.

關於本文內容 , 歡迎你們的意見跟建議

代碼倉庫 (博客配套代碼)


想得到最快更新,請關注公衆號

輸入圖片說明
在這裏輸入圖片標題
相關文章
相關標籤/搜索