Spring Boot與分布式

Spring Boot與分布式

分布式系統(tǒng)

在分布式系統(tǒng)中篱竭,國內(nèi)常用zookeeper+dubbo組合力图,而Spring Boot推薦使用全棧的Spring,Spring Boot+Spring Cloud掺逼。

distributed.png
  • 單一應(yīng)用架構(gòu)

    當(dāng)網(wǎng)站流量很小時(shí)吃媒,只需一個(gè)應(yīng)用,將所有功能都部署在一起吕喘,以減少部署節(jié)點(diǎn)和成本赘那。此時(shí),用于簡(jiǎn)化增刪改查工作量的數(shù)據(jù)訪問框架(ORM)是關(guān)鍵氯质。

  • 垂直應(yīng)用架構(gòu)

    當(dāng)訪問量逐漸增大募舟,單一應(yīng)用增加機(jī)器帶來的加速度越來越小,將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用闻察,以提升效率拱礁。此時(shí),用于加速前端頁面開發(fā)的Web框架(MVC)是關(guān)鍵辕漂。

  • 分布式服務(wù)架構(gòu)

    當(dāng)垂直應(yīng)用越來越多呢灶,應(yīng)用之間交互不可避免,將核心業(yè)務(wù)抽取出來钉嘹,作為獨(dú)立的服務(wù)鸯乃,逐漸形成穩(wěn)定的服務(wù)中心,使前端應(yīng)用能更快速的響應(yīng)多變的市場(chǎng)需求跋涣。此時(shí)缨睡,用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架(RPC)是關(guān)鍵鸟悴。

  • 流動(dòng)計(jì)算架構(gòu)

    當(dāng)服務(wù)越來越多,容量的評(píng)估宏蛉,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn)遣臼,此時(shí)需增加一個(gè)調(diào)度中心基于訪問壓力實(shí)時(shí)管理集群容量,提高集群利用率拾并。此時(shí)揍堰,用于提高機(jī)器利用率的資源調(diào)度和治理中心(SOA)是關(guān)鍵。

Zookeeper和Dubbo

Zookeeper

ZooKeeper 是一個(gè)分布式的嗅义,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù)屏歹。它是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護(hù)之碗、域名服務(wù)蝙眶、分布式同步、組服務(wù)等褪那。

Dubbo

Dubbo是Alibaba開源的分布式服務(wù)框架幽纷,它最大的特點(diǎn)是按照分層的方式來架構(gòu),使用這種方式可以使各個(gè)層之間解耦合(或者最大限度地松耦合)博敬。從服務(wù)模型的角度來看友浸,Dubbo采用的是一種非常簡(jiǎn)單的模型,要么是提供方提供服務(wù)偏窝,要么是消費(fèi)方消費(fèi)服務(wù)收恢,所以基于這一點(diǎn)可以抽象出服務(wù)提供方(Provider)和服務(wù)消費(fèi)方(Consumer)兩個(gè)角色。

dubbo.png

代碼

安裝zookeeper組件

  • 啟動(dòng)zookeeper組件

生產(chǎn)者-provider

  • 引入依賴

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Dubbo Spring Boot Starter -->
    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
      <version>2.7.4.1</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.5</version>
      <type>pom</type>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>2.12.0</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>2.12.0</version>
    </dependency>
    
  • 配置

    dubbo.application.name=provider
    dubbo.registry.address=zookeeper://192.168.1.106:2181
    dubbo.scan.base-packages=cn.net.credit.ticket.service
    
  • 代碼

    編寫TicketsService接口

    package cn.net.credit.ticket.service;
    
    public interface TicketsService {
        public String getTicker();
    }
    

    編寫TicketServiceImpl實(shí)現(xiàn)類祭往,注意@Service屬于org.apache.dubbo.config.annotation.Service

    package cn.net.credit.ticket.service;
    
    import org.apache.dubbo.config.annotation.Service;
    import org.springframework.stereotype.Component;
    
    @Component
    @Service
    public class TicketServiceImpl implements TicketsService {
        @Override
        public String getTicker() {
            return "《哪吒》";
        }
    }
    

消費(fèi)者-comsumer

先啟動(dòng)生產(chǎn)者伦意,生產(chǎn)者服務(wù)會(huì)自動(dòng)將生產(chǎn)者導(dǎo)入到zookeeper注冊(cè)中心去

  • 引入依賴

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Dubbo Spring Boot Starter -->
    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
      <version>2.7.4.1</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.5</version>
      <type>pom</type>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>2.12.0</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>2.12.0</version>
    </dependency>
    
    
  • 配置

    dubbo.application.name=comsumer
    dubbo.registry.address=zookeeper://192.168.1.106:2181
    
  • 代碼

    編寫TicketsService接口,注意與生產(chǎn)者的TicketsService目錄保持一致

    package cn.net.credit.ticket.service;
    
    public interface TicketsService {
        public String getTicker();
    }
    

    編寫UserService硼补,注意@Reference屬于org.apache.dubbo.config.annotation.Reference

    package cn.net.credit.user.service;
    
    import cn.net.credit.ticket.service.TicketsService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.stereotype.Service;
    

    @Service
    public class UserService {

  @Reference
  TicketsService ticketsService;

  public String getProvideTicket() {
      return ticketsService.getTicker();
  }

}

  > 編寫測(cè)試類

  ```java
  @SpringBootTest
  class ComsumerApplicationTests {

      @Resource
      UserService userService;
      @Test
      public void test01() {
          System.out.println("買到" + userService.getProvideTicket() +"的票了M匀狻!");
      }
  }

Spring Cloud

Spring Cloud是一個(gè)分布式的整體解決方案已骇。Spring Cloud 為開發(fā)者提供了在分布式系統(tǒng)(配置管理离钝,服務(wù)發(fā)現(xiàn),熔斷疾捍,路由奈辰,微代理,控制總線乱豆,一次性token奖恰,全局瑣,leader選舉,分布式session瑟啃,集群狀態(tài))中快速構(gòu)建的工具论泛,使用Spring Cloud的開發(fā)者可以快速的啟動(dòng)服務(wù)或構(gòu)建應(yīng)用、同時(shí)能夠快速和云平臺(tái)資源進(jìn)行對(duì)接蛹屿。

SpringCloud分布式開發(fā)五大常用組件

  • 服務(wù)發(fā)現(xiàn)——Netflix Eureka
  • 客服端負(fù)載均衡——Netflix Ribbon
  • 斷路器——Netflix Hystrix
  • 服務(wù)網(wǎng)關(guān)——Netflix Zuul
  • 分布式配置——Spring Cloud Config

代碼

創(chuàng)建Eureka注冊(cè)中心

  • 引入依賴

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  • Eureka配置

    server:
      port: 8761
    eureka:
      instance:
        hostname: eureka-server #Eureka實(shí)例的主機(jī)名
      client:
        register-with-eureka: false # 不把自己注冊(cè)到Eureka上
        fetch-registry: false # 不從Eureka上來獲取服務(wù)的注冊(cè)信息
        service-url:
          defaultZone: http://localhost:8761/eureka
    
  • 開啟Eureka服務(wù) @EnableEurekaServer

    /**
     * 注冊(cè)中心
     * 1:配置Eureka信息
     * 2:使用@EnableEurekaServer開啟Eureka服務(wù)
     */
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    
    }
    
  • 啟動(dòng)Eureka服務(wù)屁奏,訪問Eureka

    http://localhost:8761/

Eureka-server-01.png

創(chuàng)建生產(chǎn)者

  • 引入依賴

    <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
  • 配置

    server:
      port: 8001
    spring:
      application:
        name: provide-server
    eureka:
      instance:
        prefer-ip-address: true  # 注冊(cè)服務(wù)的時(shí)候使用服務(wù)的ip地址
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
  • 代碼

    TicketController

    import cn.net.provide.service.TicketService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class TicketController {
    
        @Resource
        TicketService ticketService;
    
        @GetMapping("/ticket")
        public String getTicket(){
            System.out.println("8001");
            return ticketService.getTicket();
        }
    
    }
    

    TicketService

    import org.springframework.stereotype.Service;
    
    @Service
    public class TicketService {
    
        public String getTicket(){
            return "《哪吒!4砀骸7仄啊!》";
        }
    }
    
    
  • 使用8001犹撒,8002端口折联,啟動(dòng)兩個(gè)生產(chǎn)者服務(wù)

provider.png

創(chuàng)建消費(fèi)者

  • 引入依賴

    <properties>
       <java.version>1.8</java.version>
       <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
    </properties>
    
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
    
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
          <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
    </dependencies>
    
    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-dependencies</artifactId>
          <version>${spring-cloud.version}</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    
  • 配置

    server:
      port: 8500
    spring:
      application:
        name: comsumer-user
    eureka:
      instance:
        prefer-ip-address: true  # 注冊(cè)服務(wù)的時(shí)候使用服務(wù)的ip地址
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
  • 使用 @EnableEurekaClient開啟發(fā)現(xiàn)服務(wù)功能,使用@LoadBalanced配置負(fù)載均衡機(jī)制

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.client.RestTemplateBuilder;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @EnableEurekaClient // 開啟發(fā)現(xiàn)服務(wù)功能
    @SpringBootApplication
    public class ComsumerUserApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ComsumerUserApplication.class, args);
        }
    
       @LoadBalanced // 使用負(fù)載均衡機(jī)制
       @Bean
        public RestTemplate restTemplate() {
           return new RestTemplate();
       }
    
    }
    
  • UserControl

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    
    @RestController
    public class UserControl {
        @Resource
        RestTemplate restTemplate;
    
        @GetMapping("/buy")
        public String buyTicket() {
            return "購買了" + restTemplate.getForObject("http://PROVIDE-SERVER/ticket", String.class);
        }
    }
    
  • 啟動(dòng)消費(fèi)者

    訪問 http://localhost:8500/buy 測(cè)試4次识颊,兩臺(tái)生產(chǎn)者服務(wù)器各被訪問2次

    結(jié)果:

    2-provide.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诚镰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子祥款,更是在濱河造成了極大的恐慌清笨,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刃跛,死亡現(xiàn)場(chǎng)離奇詭異抠艾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奠伪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門跌帐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來首懈,“玉大人绊率,你說我怎么就攤上這事【柯模” “怎么了滤否?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)最仑。 經(jīng)常有香客問我藐俺,道長(zhǎng),這世上最難降的妖魔是什么泥彤? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任欲芹,我火速辦了婚禮,結(jié)果婚禮上吟吝,老公的妹妹穿的比我還像新娘菱父。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布浙宜。 她就那樣靜靜地躺著官辽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粟瞬。 梳的紋絲不亂的頭發(fā)上同仆,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音裙品,去河邊找鬼俗批。 笑死,一個(gè)胖子當(dāng)著我的面吹牛市怎,可吹牛的內(nèi)容都是我干的扶镀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼焰轻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼臭觉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辱志,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蝠筑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后揩懒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體什乙,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年已球,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了臣镣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡智亮,死狀恐怖忆某,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阔蛉,我是刑警寧澤弃舒,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站状原,受9級(jí)特大地震影響聋呢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颠区,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一削锰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毕莱,春花似錦器贩、人聲如沸测暗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碗啄。三九已至,卻和暖如春稳摄,著一層夾襖步出監(jiān)牢的瞬間稚字,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工厦酬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胆描,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓仗阅,卻偏偏與公主長(zhǎng)得像昌讲,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子减噪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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