spring cloud簡介及spring cloud Eureka快速入門

最近重新梳理spring Cloud技術(shù)潦俺,從源碼層次的角度來理解spring Cloud這門技術(shù)

單體架構(gòu)

一個歸檔包包含了應(yīng)用所有功能的應(yīng)用程序, 我們通常稱之為單體應(yīng)用府怯。
架構(gòu)單體應(yīng)用的架構(gòu)風(fēng)格, 我們稱之為單體架構(gòu), 這是一種比較傳統(tǒng)的架構(gòu)風(fēng)格药磺。

單體架構(gòu).png

單體架構(gòu)的缺陷在哪里呢?筆者從這些方面來談?wù)?/strong>

  • 代碼重復(fù)問題 比如說用戶服務(wù)和訂單服務(wù)因為在一個項目下不同的包下煤伟,但是訂單相關(guān)的服務(wù)需要用戶服務(wù)的一些接口癌佩,直接查詢用戶相關(guān)的表直接查詢,然后提供給自己的訂單服務(wù)自己使用便锨,這就造成了很多代碼的重復(fù)围辙,很多sql查詢直接出現(xiàn)在訂單服務(wù)的Dao和Service層,類似的情況放案,比如說支付服務(wù)也需要類似的用戶數(shù)據(jù)等等姚建。
  • 環(huán)境依賴問題 每個服務(wù)依賴的外部環(huán)境不一樣,比如說訂單服務(wù)依賴于kafka吱殉,商品服務(wù)依賴于es等等桥胞,但是在準(zhǔn)備資源的時候可能上線商品服務(wù),就忽略了訂單服務(wù)的依賴環(huán)境的問題考婴,比如說訂單服務(wù)上線前要創(chuàng)建一些隊列啥的贩虾,或者要初始化自己服務(wù)的一些數(shù)據(jù),但是因為在單體應(yīng)用中沥阱,這塊可能因為商品服務(wù)相關(guān)服務(wù)發(fā)版缎罢,造成訂單服務(wù)的問題等等
  • 擴(kuò)容問題 每個服務(wù)的壓力不一樣,可能訂單服務(wù)更快的達(dá)到瓶頸考杉,需要擴(kuò)容策精,但是用戶服務(wù)在單體應(yīng)用中的內(nèi)存中維護(hù)了一些用戶狀態(tài),不能進(jìn)行擴(kuò)容崇棠;還有就是只是你訂單服務(wù)的擴(kuò)容咽袜,為什么用戶服務(wù)我也要承擔(dān)相應(yīng)的風(fēng)險。
  • 可用性問題 一個模塊的崩潰會造成整個服務(wù)的不可用枕稀,造成整個cpu 100%询刹,出現(xiàn)oom谜嫉,jvm內(nèi)存溢出,整個系統(tǒng)的不可用凹联。

還有比如說git沖突沐兰,功能沖突,每次迭代不同服務(wù)的模塊蔽挠,合并分支都要進(jìn)行全部服務(wù)的回歸測試等等住闯,問題很多于是就出現(xiàn)了微服務(wù)架構(gòu)。

什么是微服務(wù)架構(gòu)

微服務(wù)架構(gòu)源于Martin Fowler的一篇博文地址.

微服務(wù)架構(gòu)就是為了解決單體應(yīng)用架構(gòu)的這些問題澳淑,服務(wù)之間的交互通過接口的方式來實現(xiàn)比原,每個服務(wù)獨立運維部署,每個服務(wù)都有自己的環(huán)境杠巡,比如說有自己的數(shù)據(jù)庫量窘,有自己的緩存服務(wù)等等。

簡陋版的微服務(wù)架構(gòu).png

項目微架構(gòu)中所不可避免的問題忽孽,比如說分布式事務(wù)绑改,認(rèn)證授權(quán)谢床,分布式作業(yè)等等問題兄一。

spring cloud簡介

spring cloud是一個基于spring boot實現(xiàn)的微服務(wù)架構(gòu)開發(fā)工具。它為微服務(wù)架構(gòu)中涉及的配置管理识腿,服務(wù)治理出革,斷路器,智能路由渡讼,微代理骂束,控制總線,全局鎖成箫,決策競選展箱,分布式會話和集群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。spring Cloud版本是采用了倫敦地鐵站的名字蹬昌,根據(jù)字母表的順序來對應(yīng)版本時間順序混驰,比如最早的Release版本的Angel,第二個Release版本的Brixton.....

spring cloud Eureka

spring cloud Eureka是spring cloud Netfix微服務(wù)套件中的一部分皂贩,它基于Netfix Eureka做了二次封裝栖榨,主要負(fù)責(zé)完成微服務(wù)架構(gòu)中的服務(wù)治理功能。Spring cloud通過為Eureka增加了Spring boot風(fēng)格的自動化配置明刷,我們只需要通過簡單引入依賴和注解配置就能讓spring boot構(gòu)建微服務(wù)應(yīng)用輕松地與EUreka服務(wù)治理體系進(jìn)行整合婴栽。

在最初開始構(gòu)建微服務(wù)系統(tǒng)的時候可能服務(wù)并不多,我們可以通過一些靜態(tài)配置來完成服務(wù)的調(diào)用辈末。比如愚争,有二個服務(wù)A和B映皆,其中服務(wù)A需要調(diào)用B來完成業(yè)務(wù)操作,為了實現(xiàn)B的高可用准脂,不論采用服務(wù)端負(fù)載均衡還是客戶端負(fù)載均衡劫扒,都需要手工維護(hù)B的具體實例清單。但是隨著業(yè)務(wù)的發(fā)展狸膏,系統(tǒng)功能的復(fù)雜性越來越高沟饥,相應(yīng)的微服務(wù)也不斷增加,我們的靜態(tài)配置就會變得越來越難以維護(hù)湾戳。并且面對不斷發(fā)展的業(yè)務(wù)贤旷,我們的集群規(guī)模,服務(wù)的位置砾脑,服務(wù)的命名都有可能發(fā)生變化幼驶,還是通過手工維護(hù)的方式,極其容易出現(xiàn)問題韧衣。

為了解決微服務(wù)架構(gòu)中的服務(wù)實例維護(hù)問題盅藻,產(chǎn)生了大量的服務(wù)治理框架和產(chǎn)品。這些框架和產(chǎn)品的實現(xiàn)都圍繞服務(wù)注冊與服務(wù)發(fā)現(xiàn)機(jī)制來完成對微服務(wù)應(yīng)用實例的自動化管理畅铭。如果我們使用過阿里的dubbo就知道氏淑,zookeeper也是實現(xiàn)服務(wù)注冊與發(fā)現(xiàn)的一種策略。當(dāng)然springcloud 也支持使用zookeeper進(jìn)行服務(wù)治理硕噩。

快速入門

1假残、搭建工程
用最新版本的spring cloud,Edgware.SR3炉擅,搭建一個聚合工程辉懒,以便于idea開發(fā),在父pom文件中定義springboot和springcloud的版本:

pom.xml文件:

    <modules>
        <module>eureka-server</module>
        <module>serviceA</module>
        <module>serviceB</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2谍失、定義eureka-server服務(wù):

pom.xml

   <artifactId>eureka-server</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>

服務(wù)啟動類眶俩,加上@EnableEurekaServer注解:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class, args);
    }

}

定義的配置文件application.yml:

server:
  port: 8761
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

啟動服務(wù):

2018-08-12 16:34:25.924  INFO 5454 --- [           main] c.n.eureka.cluster.PeerEurekaNodes       : Replica node URL:  http://localhost:8761/eureka/
2018-08-12 16:34:25.934  INFO 5454 --- [           main] c.n.e.registry.AbstractInstanceRegistry  : Finished initializing remote region registries. All known remote regions: []
2018-08-12 16:34:25.935  INFO 5454 --- [           main] c.n.eureka.DefaultEurekaServerContext    : Initialized
2018-08-12 16:34:25.953  WARN 5454 --- [           main] arterDeprecationWarningAutoConfiguration : spring-cloud-starter-eureka is deprecated as of Spring Cloud Netflix 1.4.0, please migrate to spring-cloud-starter-netflix-eureka
2018-08-12 16:34:25.956  WARN 5454 --- [           main] arterDeprecationWarningAutoConfiguration : spring-cloud-starter-eureka-server is deprecated as of Spring Cloud Netflix 1.4.0, please migrate to spring-cloud-starter-netflix-eureka-server
2018-08-12 16:34:26.118  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-08-12 16:34:26.131  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
2018-08-12 16:34:26.132  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshEndpoint' has been autodetected for JMX exposure
2018-08-12 16:34:26.132  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'environmentManager' has been autodetected for JMX exposure
2018-08-12 16:34:26.133  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'serviceRegistryEndpoint' has been autodetected for JMX exposure
2018-08-12 16:34:26.134  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'refreshScope' has been autodetected for JMX exposure
2018-08-12 16:34:26.137  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
2018-08-12 16:34:26.150  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'serviceRegistryEndpoint': registering with JMX server as MBean [org.springframework.cloud.client.serviceregistry.endpoint:name=serviceRegistryEndpoint,type=ServiceRegistryEndpoint]
2018-08-12 16:34:26.157  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
2018-08-12 16:34:26.169  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=408613cc,type=ConfigurationPropertiesRebinder]
2018-08-12 16:34:26.175  INFO 5454 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'refreshEndpoint': registering with JMX server as MBean [org.springframework.cloud.endpoint:name=refreshEndpoint,type=RefreshEndpoint]
2018-08-12 16:34:26.189  INFO 5454 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-08-12 16:34:26.189  INFO 5454 --- [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application unknown with eureka with status UP
2018-08-12 16:34:26.235  INFO 5454 --- [      Thread-26] o.s.c.n.e.server.EurekaServerBootstrap   : Setting the eureka configuration..
2018-08-12 16:34:26.235  INFO 5454 --- [      Thread-26] o.s.c.n.e.server.EurekaServerBootstrap   : Eureka data center value eureka.datacenter is not set, defaulting to default
2018-08-12 16:34:26.236  INFO 5454 --- [      Thread-26] o.s.c.n.e.server.EurekaServerBootstrap   : Eureka environment value eureka.environment is not set, defaulting to test
2018-08-12 16:34:26.248  INFO 5454 --- [      Thread-26] o.s.c.n.e.server.EurekaServerBootstrap   : isAws returned false
2018-08-12 16:34:26.248  INFO 5454 --- [      Thread-26] o.s.c.n.e.server.EurekaServerBootstrap   : Initialized server context
2018-08-12 16:34:26.248  INFO 5454 --- [      Thread-26] c.n.e.r.PeerAwareInstanceRegistryImpl    : Got 1 instances from neighboring DS node
2018-08-12 16:34:26.248  INFO 5454 --- [      Thread-26] c.n.e.r.PeerAwareInstanceRegistryImpl    : Renew threshold is: 1
2018-08-12 16:34:26.248  INFO 5454 --- [      Thread-26] c.n.e.r.PeerAwareInstanceRegistryImpl    : Changing status to UP
2018-08-12 16:34:26.254  INFO 5454 --- [      Thread-26] e.s.EurekaServerInitializerConfiguration : Started Eureka Server
2018-08-12 16:34:26.298  INFO 5454 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8761 (http)
2018-08-12 16:34:26.298  INFO 5454 --- [           main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8761
2018-08-12 16:34:26.303  INFO 5454 --- [           main] com.zhihao.miao.eureka.EurekaServer      : Started EurekaServer in 7.094 seconds (JVM running for 8.472)

打開eureka管控臺:

http://localhost:8761/

3、創(chuàng)建A服務(wù)(服務(wù)提供者)

創(chuàng)建服務(wù)提供者工程快鱼,其實微服務(wù)中沒有嚴(yán)格意義上的服務(wù)提供者和服務(wù)消費者痢甘,只是針對于一次調(diào)用關(guān)系

pom.xml文件:

   <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

定義項目啟動類掷豺,加上@EnableEurekaClient注解:

@SpringBootApplication
@EnableEurekaClient
public class ServiceAApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceAApplication.class, args);
    }

}

定義一個接口:

@RestController
public class ServiceAController {

    @RequestMapping(value = "/sayHello/{name}",
            method = RequestMethod.GET)
    public String sayHello(@PathVariable("name") String name) {
        return "{'msg': 'hello, " + name + "'}";
    }

}

定義配置文件application.yml:

server:
  port: 8088
spring:
  application:
    name: ServiceA
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

4外傅、定義服務(wù)消費者BService:

首先定義的pom文件羊瘩,這邊的ribbon跟負(fù)載均衡有關(guān)系:

    <artifactId>serviceB</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
    </dependencies>

然后定義項目啟動類:

@SpringBootApplication
@EnableEurekaClient
public class ServiceBApplication {

    public static void main(String[] args) throws Exception{
        SpringApplication.run(ServiceBApplication.class, args);



    }

}

定義一個接口去調(diào)用服務(wù)A接口:

@RestController
@Configuration
public class ServiceBController {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @RequestMapping(value = "/greeting/{name}", method = RequestMethod.GET)
    public String greeting(@PathVariable("name") String name) {
        RestTemplate restTemplate = getRestTemplate();
        return restTemplate.getForObject("http://ServiceA/sayHello/" + name, String.class);
    }

}

這邊先劇透一下RestTemplate類跟負(fù)載均衡組件有關(guān),相關(guān)的下面會去講解:

@RestController
@Configuration
public class ServiceBController {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @RequestMapping(value = "/greeting/{name}", method = RequestMethod.GET)
    public String greeting(@PathVariable("name") String name) {
        RestTemplate restTemplate = getRestTemplate();
        return restTemplate.getForObject("http://ServiceA/sayHello/" + name, String.class);
    }

}

配置文件application.xml:

server:
  port: 9090
spring:
  application:
    name: ServiceB
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

啟動服務(wù):

然后在瀏覽器里訪問柒莉,http://localhost:9090/greeting/miaozhihao闻坚,就可以看到結(jié)果了

git地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兢孝,隨后出現(xiàn)的幾起案子窿凤,更是在濱河造成了極大的恐慌仅偎,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雳殊,死亡現(xiàn)場離奇詭異橘沥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)夯秃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門座咆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仓洼,你說我怎么就攤上這事介陶。” “怎么了色建?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵哺呜,是天一觀的道長。 經(jīng)常有香客問我箕戳,道長某残,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任陵吸,我火速辦了婚禮玻墅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘走越。我一直安慰自己椭豫,他們只是感情好耻瑟,可當(dāng)我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布旨指。 她就那樣靜靜地躺著,像睡著了一般喳整。 火紅的嫁衣襯著肌膚如雪谆构。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天框都,我揣著相機(jī)與錄音搬素,去河邊找鬼。 笑死魏保,一個胖子當(dāng)著我的面吹牛熬尺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谓罗,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼粱哼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了檩咱?” 一聲冷哼從身側(cè)響起揭措,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤胯舷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绊含,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桑嘶,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年躬充,在試婚紗的時候發(fā)現(xiàn)自己被綠了逃顶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡充甚,死狀恐怖口蝠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情津坑,我是刑警寧澤妙蔗,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站疆瑰,受9級特大地震影響眉反,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜穆役,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一寸五、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耿币,春花似錦梳杏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至塑悼,卻和暖如春劲适,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背厢蒜。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工霞势, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斑鸦。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓愕贡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巷屿。 傳聞我的和親對象是個殘疾皇子固以,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容