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

object君發表於2019-02-26

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

但是細想想,是真的麼?,忙到這幾個字都沒時間打麼?畢竟大家都很忙的,所以忙併不是啥理由.

那是因為啥呢?感覺就只有一個理由能站得住腳了,就是因為”懶”. 哈哈….

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

場景

在實際工作中,大家可能也都遇到過這樣的情況 :

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

而專案的onwer則需要接收到這些需求,對這些需求進行初步的分析和排期,但是在排期的過程中,會有這樣一種尷尬的情況發生.

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

那麼,對於這種情況,通常會採用開分支的方式進行開發,即不同版本的並行需求的開發在不同分支上同時進行開發,那麼,團隊成員(開發/測試),則可以同時的開展工作,有的負責A需求,有的負責B需求,互不影響

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

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;
    }
}
複製程式碼

結束

這樣一來,在不增加任何環境資源的前提下,可以實現不同版本服務的服務同時釋出.滿足了並行整合測試的需求

當然,還是那句話,解決同樣問題的方法有多種,我上述的方法也不一定是最好的,如果有更好經驗的同學,歡迎大家踴躍討論.

關於本文內容 , 歡迎大家的意見跟建議

程式碼倉庫 (部落格配套程式碼)


想獲得最快更新,請關注公眾號

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

相關文章