java代碼生成器集成dubbo,springcloud詳解以及微服務遐想

摘要

??今天終于有了點空閑時間,所以更新了一下代碼生成器,修復了用戶反饋的bug,本次更新主要增加了dubbo和springcloud腳手架的下載功能,架子是本人親自搭建,方便自由擴展或者小白學習使用,你也許會問為什么它們不能像springboot一樣通過配置的方式生成項目,我只能回答:理論上是可以的,以后有時間會摸索可行之道,但是我覺得微服務框架業(yè)務復雜多變,不如直接使用腳手架自由擴展來的方便,所以目前是采用了這樣一種方式。本篇博客將具體介紹腳手架每個部分的功能模塊,然后暢想一下微服務技術的未來發(fā)展趨勢。

dubbo腳手架

??dubbo曾經(jīng)風靡一時,但是逐步被springcloud所替代,所以dubbo的腳手架我做的相對簡易,以表緬懷之情。
??代碼生成器獲取dubbo腳手架十分簡單,如下:

dubbo

??鼠標點擊一下便可自動下載到桌面
拉取dubbo

??然后看一下腳手架的目錄結構:
dubbo目錄

??項目導入到了idea當中,因為dubbo需要zookeeper依賴,所以需要配置zookeeper注冊中心,相信你可以自己解決~
??具體的細節(jié)請參考我的dubbo+zookeeper對比springCloud及分布式項目搭建詳解此篇博客,這個腳手架就是博客當中講述的demo項目。

springcloud腳手架

??把springcloud腳手架下載下來導入到idea當中,項目結構如下:


springcloud

??下面對每個module的配置進行簡要講解,其他的細節(jié)讀者可以使用生成器下載自行查看。

cloud_eureka模塊

??此模塊主要負責服務發(fā)現(xiàn)注冊,相當于dubbo的zookeeper,只不過springCloud使用eureka來進行服務的發(fā)現(xiàn)和注冊,相信大家都知道CAP原則,即一致性,可用性和分區(qū)容錯性,只要是分布式項目,一般都具備分區(qū)容錯性(簡單理解,一個節(jié)點掛了,其他節(jié)點可以正常提供服務)。
??zookeeper本身就不是為高可用設計的,節(jié)點之間的數(shù)據(jù)會保持高度的同步,并且一旦發(fā)生網(wǎng)絡隔離,zookeeper內(nèi)部會進行master選舉,這個選舉流程是十分緩慢的,長達30到120秒,對于一個要不斷向外界提供服務的系統(tǒng)來說,這將是非常致命的!所以dubbo+zookeeper總體來說符合CP原則。
??springcloud的服務注冊中心eureka則不同,eureka每個節(jié)點都是平等的,不會有選舉master節(jié)點這一說法,并且本身具有自我保護機制,具備服務的高度可用性,相對的,它無法做到數(shù)據(jù)的強一致,也就是無法保證在每個節(jié)點上始終獲取的都是最新的數(shù)據(jù),但我們可以在程序設計的時候保證結果的最終一致性。所以springcloud總體來說符合AP原則。
??讓我們看一下cloud_eureka的yml配置,如下:通過加載不同的yml,就可以分別啟動server1和server2構成eureka集群,負責服務發(fā)現(xiàn)和注冊的職責。
??application.yml:

#注冊中心應用名稱
spring:
  application:
    name: eureka-server
#使用的配置文件名 `java -jar -Dspring.profiles.active=serverX demo.jar`啟動serverX配置
  profiles:
    active: server1

??application-server1.yml:

#注冊中心運行的端口號
server:
  port: 8001
#注冊中心應用名稱
#spring:
#  application:
#      name: eureka-server
#eureka.server.enableSelfPreservation:是否向注冊中心注冊自己
#通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server.
eureka:
# 自我保護機制
  #server:
     #enableSelfPreservation: false #關閉eureka的自我保護 小規(guī)模項目關閉比較好
     #eviction-interval-timer-in-ms: 5000 #清理間隔時間,單位為毫秒(默認值60 * 1000)
     #use-read-only-response-cache: false
  instance:
      hostname: server1
      prefer-ip-address: false
#      ip-address: 172.193.225.185
#      instance-id: ${spring.cloud.client.ipAddress}:${server.port}
  client:
      fetch-registry: true 
      register-with-eureka: true 
      service-url:
           defaultZone: http://server2:8002/eureka/

??application-server2.yml:

#注冊中心運行的端口號
server:
  port: 8002
#注冊中心應用名稱
#spring:
#  application:
#      name: eureka-server
#eureka.server.enableSelfPreservation:是否向注冊中心注冊自己
#通過eureka.client.registerWithEureka:false和fetchRegistry:false來表明自己是一個eureka server.
eureka:
# 自我保護機制
  #server:
     #enableSelfPreservation: false #關閉eureka的自我保護 小規(guī)模項目關閉比較好
     #eviction-interval-timer-in-ms: 3000 #清理間隔時間,單位為毫秒(默認值60 * 1000)
     #use-read-only-response-cache: false
  instance:
      hostname: server2
      prefer-ip-address: false
#      ip-address: 172.193.225.185
#      instance-id: ${spring.cloud.client.ipAddress}:${server.port}
  client:
      fetch-registry: true 
      register-with-eureka: true 
      service-url:
           defaultZone: http://server1:8001/eureka/

cloud_zuul模塊

??此模塊是所有微服務的網(wǎng)關,這里采用的是zuul,現(xiàn)在spring官方逐漸放棄了zuul,而是采用了自己的gateway網(wǎng)關組件,因為zuul是io阻塞的,但在配置上可以類比zuul的配置。網(wǎng)關組件也是需要在eureka中進行注冊的。
??application.yml如下,ribbon和hystrix的超時時間需要特別配置一下,不然項目啟動之后第一次通過網(wǎng)關訪問服務大概率會報hystrix timeout的超時錯誤(默認超時時間很短),ribbon負責負載均衡,hystrix負責服務熔斷,所以配置上服務熔斷的時間應該大于負載均衡的總時間,否則會一直有warn提示。
服務熔斷的超時時間計算公式如下:
(1+MaxAutoRetries + MaxAutoRetriesNextServer)* ReadTimeout,加1是因為首次訪問不計入重試次數(shù),MaxAutoRetries為同一臺實例最大調(diào)用次數(shù),默認為1,MaxAutoRetriesNextServer為切換其他實例的最大次數(shù),默認為1,所以熔斷器的超時時間要大于重試時間,不然重試就失去了意義,這里通過計算超時時間為20000,所以hystrix的超時時間設置為比20000稍大的30000即可。

#網(wǎng)關
spring:
  application:
    name: cloud-zuul
eureka:
  client:
    service-url:
      defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/
  instance:
    prefer-ip-address: true
server:
  port: 7001
zuul:
  routes:
    cloud-service1: #測試service1
      path: /service1/**
      serviceId: cloud-service1
    cloud-service2: #測試service1
      path: /service2/**
      serviceId: cloud-service2
  host:
    connect-timeout-millis: 15000
    socket-timeout-millis: 10000

ribbon:
  ConnectTimeout: 5000
  ReadTimeout: 5000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000

cloud_config模塊

??此模塊為springcloud配置中心,可以從遠程git倉庫拉取配置文件,同時它不需要注冊到eureka當中。
??application.yml內(nèi)容如下:rabbitmq的配置主要是實現(xiàn)服務總線的作用。用戶向config發(fā)送http://localhost:6001/actuator/bus-refresh請求,config會向rabbitmq發(fā)送配置更新的消息,同時配置了服務總線的微服務模塊會監(jiān)聽到此消息,就會重新從遠程拉取配置文件并重新加載,這樣我們在遠程倉庫修改了配置文件無需重啟項目就可以實現(xiàn)配置的更新。

server:
  port: 6001
spring:
  application:
    name: cloud-config
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/zrxjava/cloudModel_config.git
  rabbitmq:
    host: 127.0.0.1
    username: guest
    password: guest
#刷新總線的接口
management:
  endpoints:
    jmx:
      exposure:
        exclude: bus-refresh

cloud_service1模塊

??service1為其中的一個微服務模塊,同時它也注冊在eureka當中,在service1中,使用了feign來調(diào)用service2,我們知道,微服務可以通過ribbon和feign來調(diào)用,不同的是,ribbon采用restTemplate的方式調(diào)用,feign則是把ribbon封裝了一層,采用接口形式調(diào)用,并且默認支持負載均衡,同時也可選擇開啟服務熔斷,feign客戶端代碼如下:

package consumer.client;

import consumer.client.impl.Service2ClientImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

@Component //僅僅是為了屏蔽idea誤顯示的注入錯誤
@FeignClient(value = "cloud-service2", fallback = Service2ClientImpl.class)
public interface Service2Client {

    @GetMapping("/test/do")
    public String test();

}
package consumer.client.impl;

import consumer.client.Service2Client;
import org.springframework.stereotype.Component;

//熔斷器執(zhí)行的方法
@Component
public class Service2ClientImpl implements Service2Client {


    @Override
    public String test() {
        return "觸發(fā)熔斷器!";
    }
}

??service1的配置文件通過config配置中心管理,啟動service1的時候會加載bootstrap.yml的配置,從gitee上拉取配置文件,config配置中心主要是為了方便運維,配置上springcloud-bus后可以無需重啟項目加載配置文件,實乃運維之福音。bootstrap.yml內(nèi)容如下:

spring:
  cloud:
    config:
      name: service1 #對應git服務器上的name #name-profile
      profile: dev #對應git服務器上的profile
      label: master #提交到master分支
      uri: http://localhost:6001 #config的訪問地址

??gitee倉庫service-dev.yml內(nèi)容如下:

#注冊中心應用名稱
spring:
  application:
    name: cloud-service1
  rabbitmq:
      host: 127.0.0.1
      username: guest
      password: guest
eureka:
  client:
    service-url:
      defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/
  instance:
    prefer-ip-address: true
server:
  port: 9001
feign:
  hystrix:
    enabled: true
ribbon:
  ConnectTimeout: 5000
  ReadTimeout: 5000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000

cloud_service2模塊

??service2跟service1同樣注冊進了eureka中,同時也僅僅是注冊進入了eureka中供service1調(diào)用,在真實的項目當中,每個微服務是可以互相調(diào)用的,只是我在這里偷了個懶,沒有配置feign的客戶端調(diào)用,也就是說,它同樣可以調(diào)用service1。
??application.yml如下:

#注冊中心應用名稱
spring:
  application:
    name: cloud-service2
eureka:
  client:
    service-url:
      defaultZone: http://server1:8001/eureka/,http://server2:8002/eureka/
  instance:
    prefer-ip-address: true
server:
  port: 9002

測試

??首先我們啟動兩個eureka構成集群,分別使用server1和server2文件啟動項目(先啟動的一方由于另一方?jīng)]有啟動會報錯,當另一方啟動完畢報錯即會自動消失,因為兩方是互相注冊形成高可用集群),啟動完畢后,訪問http://localhost:8001/即可看到server1界面,如下:

eureka-server1

??同樣,server2也是可以正常訪問的,這里就不再截圖了。
??接下里啟動配置中心,注意service1的yml需要通過config遠程獲取,所以需要先啟動配置中心config,然后再分別啟動service1和service2,最后啟動zuul。如果沒有配置rabbitmq,啟動config和service1會報錯失?。ㄌ崾緹o法連接rabbitmq服務),不啟動它們也可。全部啟動完畢后,發(fā)現(xiàn)eureka注冊中心已經(jīng)有了各自的服務注冊信息,如圖:
啟動完畢

??如上圖,我們成功啟動了兩個service微服務和zuul服務網(wǎng)關。在這里eureka界面的紅色字體是由于eureka的自我保護機制觸發(fā)的,并不是報錯,當eureka收到的最后一分鐘服務實例續(xù)約的總數(shù)/每分鐘期望收到的續(xù)約數(shù)<85%的時候,便會觸發(fā)自我保護機制告訴你可能有節(jié)點出了問題(比如網(wǎng)絡延遲,并不是服務真的掛了),但是它不會去剔除它,會保留其注冊信息,等到節(jié)點恢復正常仍然可以繼續(xù)工作,這樣使得整個服務更加高可用。
??最后我們通過zuul網(wǎng)關地址訪問service1的服務(service1會通過feign調(diào)用service2),訪問http://localhost:7001/service1/test/do(如果沒有啟動config和service1,訪問http://localhost:7001/service2/test/do),如下:
結果

??這樣一來,整個流程就結束了,springcloud的核心組件也就講解完畢。

微服務遐想

??值得一提的是,在真實的微服務項目中,服務的數(shù)量遠遠不止這些,代碼生成器也只是幫助你搭建了基本的架構模型。所以如果通過人工部署管理的方式會變得異常困難,但后來隨著容器化技術的發(fā)展,通過dockerfile把每個服務生成鏡像在dokcer容器中運行漸漸成為一種主流的部署運維方式,并且通過maven插件可以一鍵構建dockerfile文件生成鏡像并上傳至docker私服,通過docker私服便可以上傳我們自己的微服務鏡像文件并十分方便的運行它們,通過jenkins持續(xù)集成,同時也讓微服務發(fā)布更加的容易,最后為了統(tǒng)一管理docker容器,k8s超過docker swarm成為容器化應用的新一代寵兒,時代在飛速發(fā)展,技術的迭代也同樣迅速!
??前陣子跟朋友微信閑聊,了解到Service Mesh技術正在悄然興起,大廠已經(jīng)有了落地應用,簡單理解,service mesh把每個微服務做了進一步的解耦,把通信相關的操作(負載均衡,斷路器等)抽離了出來,為每個微服務生成了一個代理服務,而微服務做到了真正只需要關心業(yè)務。以前的微服務是單輪車,現(xiàn)在變成了雙輪車,所以有人也稱它為“邊車模式“,把每個代理服務用線連接起來,組成了一個錯綜復雜的網(wǎng)格,service mesh也就由此而來,后來演化出了集中式的控制面板來管理一個個的網(wǎng)格,代表作品:Istio。
??但同樣的,由于service mesh接管了網(wǎng)絡流量,系統(tǒng)的穩(wěn)定性就會依賴于service mesh,同時相比之前,額外引入的大量service mesh實例對運維和管理來說也是一個巨大的挑戰(zhàn)。
??service mesh是未來微服務的發(fā)展趨勢,歷史也總是驚人的相似,最開始的時候,人們?yōu)榱私鉀Q端到端的通信問題,tcp協(xié)議橫空出世,多機通信從此變得簡單可靠。如今我們來到了微服務時代,為了屏蔽分布式系統(tǒng)的通信復雜性,service mesh應運而生。這讓我們回歸業(yè)務,聚焦真正的價值!

代碼生成器:點擊下載

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 微服務架構模式的核心在于如何識別服務的邊界,設計出合理的微服務。但如果要將微服務架構運用到生產(chǎn)項目上,并且能夠發(fā)揮...
    java菜閱讀 3,045評論 0 6
  • 前言 一段時期以來 “微服務架構 ”一直是一個熱門詞匯,各種技術類公眾號或架構分享會議上,關于微服務架構的討論和主...
    風平浪靜如碼閱讀 568評論 0 0
  • 一 概述 關于微服務的介紹目前已經(jīng)有很多文章做了介紹,本文不再對微服務的概念再做進一步闡述,重點將介紹微服務架構具...
    java菜閱讀 5,497評論 0 5
  • 明英宗(正統(tǒng)帝、天順帝)雖算不上什么好皇帝,但他是個“好家長”:好丈夫——不搞專寵,雨露均沾;好父親——皇長子朱見...
    一夕厘閱讀 1,837評論 2 20
  • 風 罵罵咧咧 訴說云彩的不是 雨 跌跌撞撞 傾訴愛的新意 陽光 被羞得躲起來 陰云密布 不再主持朝政 飲煙 把一縷...
    燕銜紅泥閱讀 272評論 2 8

友情鏈接更多精彩內(nèi)容