SpringBoot 整合篇 筆記--Spring Boot與分布式


SpringBoot 整合篇 筆記--Spring Boot與分布式

分布式應用

在分布式系統中,國內常用zookeeper+dubbo組合,而Spring Boot推薦使用
全棧的Spring,Spring Boot+Spring Cloud
分布式系統:
  
  • 單一應用架構
    當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的數據訪問框架(ORM)是關鍵。
  • 垂直應用架構
    當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。
  • 分布式服務架構
    當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,
用於提高業務復用及整合的分布式服務框架(RPC)是關鍵。
  • 流動計算架構
    當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利 用率的資源調度和治理中心(SOA)是關鍵。

Zookeeper和Dubbo

ZooKeeper注冊中心
ZooKeeper 是一個分布式的,開放源碼的分布式應用程序協調服務。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。

Dubbo分布式服務調用框架
Dubbo是Alibaba開源的分布式服務框架,它最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地松耦合)。從服務模型的角度來看,Dubbo采用的是一種非常簡單的模型,要么是提供方提供服務,要么是消費方消費服務,所以基於這一點可以抽象出服務提供方(Provider)和服務消費方(Consumer)兩個角色。

Dubbo分布式運行流程

具體代碼實現

  1、安裝zookeeper作為注冊中心
  2、編寫服務提供者
  3、編寫服務消費者
  4、整合dubbo

  <dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
  </dependency>

服務者:

/**
*      1、將服務提供者注冊到注冊中心
* 1、引入dubbo和zkclient相關依賴
* 2、配置dubbo的掃描包和注冊中心地址
* 3、使用@Service發布服務
*/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>provider-ticket</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider-ticket</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.1.0</version>
        </dependency>

        <!--引入zookeeper的客戶端工具-->
        <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


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

</project>
pom
#application.properties
   dubbo.application.name=provider-ticket   dubbo.registry.address=zookeeper://10.87.3.137:2181   dubbo.scan.base-packages=com.example.providerticket.service
package com.example.providerticket.controller;

import com.example.providerticket.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {
    @Autowired
    TicketService ticketService;

    @GetMapping("/ticket")
    public String getTicket(){
        return ticketService.getTicket();
    }
}
TicketController
package com.example.providerticket.service;

import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

@Component  //加到容器中
@Service //將服務發布出去,是dubbo的service
public class TicketServiceImpl implements TicketService  {
    @Override
    public String getTicket() {
        return "《厲害了,我的國》";
    }
}
TicketServiceImpl
package com.example.providerticket.service;

public interface TicketService {
    public String getTicket();
}
TicketService

消費者:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>consumer-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer-user</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.1.0</version>
        </dependency>

        <!--引入zookeeper的客戶端工具-->
        <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>
pom
#application.properties
  dubbo.application.name=consumer-user   dubbo.registry.address=zookeeper://10.87.3.137:2181 
package com.example.consumeruser.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.example.providerticket.service.TicketService;
import org.springframework.stereotype.Service;

@Service//Spring的service
public class UserService {
    @Reference//注意兩個工程的全類名相同
    TicketService ticketService;

    public void hello(){
        String ticket = ticketService.getTicket();
        System.out.println("買到票了:"+ticket);
    }

}
UserService
package com.example.providerticket.service;

public interface TicketService {
    public String getTicket();
}
TicketService 加入 服務者模塊可以 進行調用

 測試: 

package com.example.consumeruser;

import com.example.consumeruser.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ConsumerUserApplicationTests {

    @Autowired
    UserService userService;
    @Test
    public   void contextLoads() {
        userService.hello();
    }

}
ConsumerUserApplicationTests

Spring Boot和Spring Cloud

Spring Cloud
Spring Cloud是一個分布式的整體解決方案。Spring Cloud 為開發者提供了在分布式系統( 置管理,服務發現,熔斷,路由,微代理,控制總線,一次性token,全局瑣,leader選舉,分 布式session,集群狀態)中快速構建的工具,使用Spring Cloud的開發者可以快速的啟動服務
或構建應用、同時能夠快速和雲平台資源進行對接。
 
• SpringCloud分布式開發五大常用組件
  • 服務發現——Netflix Eureka
  • 客服端負載均衡——Netflix Ribbon
  • 斷路器——Netflix Hystrix
  • 服務網關——Netflix Zuul
  • 分布式配置——Spring Cloud Config

 Spring Cloud 入門
1、創建provider
2、創建consumer
3、引入Spring Cloud
4、引入Eureka注冊中心
5、引入Ribbon進行客戶端負載均衡

代碼實現

新建空工程:

創建注冊中心:eureka-server 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.14.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR6</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </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>

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

</project>
pom
server:
  port: 8761
eureka:
  instance:
    hostname: eureka-server  # eureka實例的主機名
  client:
    register-with-eureka: false #不把自己注冊到eureka上
    fetch-registry: false #不從eureka上來獲取服務的注冊信息
    service-url:
      defaultZone: http://localhost:8761/eureka/
yml  
package com.example.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer  //開啟服務
@SpringBootApplication
public class EurekaServerApplication {

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

}
EurekaServerApplication

啟動注冊中心:

踩坑1:請求是IP+端口,沒有上下文

踩坑2:啟動類要開啟 @EnableEurekaServer

創建服務者:provider-ticket

server:
  port: 8002
spring:
  application:
    name: provider-ticket


eureka:
  instance:
    prefer-ip-address: true # 注冊服務的時候使用服務的ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

application.yml
yml

package com.example.providerticket.service;

import org.springframework.stereotype.Service;

@Service
public class TicketServiceImpl implements TicketService  {
    @Override
    public String getTicket() {
        return "《厲害了,我的國》";
    }
}
TicketServiceImpl
package com.example.providerticket.controller;

import com.example.providerticket.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {
    @Autowired
    TicketService ticketService;

    @GetMapping("/ticket")
    public String getTicket(){
        return ticketService.getTicket();
    }
}
TicketController

創建消費者:consumer-user

spring:
  application:
    name: consumer-user
server:
  port: 8200

eureka:
  instance:
    prefer-ip-address: true # 注冊服務的時候使用服務的ip地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

application.yml
yml
package com.example.consumeruser;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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
@SpringBootApplication
public class ConsumerUserApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerUserApplication.class, args);
    }
    @LoadBalanced //使用負載均衡機制
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
ConsumerUserApplication
package com.example.consumeruser.cotroller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class UserController {
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/buy")
    public String buyTicket(String name){
        String s = restTemplate.getForObject("http://PROVIDER-TICKET/ticket", String.class);
        return name+"購買了"+s;
    }
}
UserController

測試:

 

SpringBoot與SpringCloud的版本對應詳細版

關於maven倉庫的版本列表

spring-cloud-dependencies 版本列表可查看:
  https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies


spring-boot-starter-parent 版本列表可查看:
  https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent 

版本對應關系

 

 

 關於spring cloud1.x版本和2.x版本區別

1.x版本pom.xml里幾個基本用到的jar長這樣:  

              <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zipkin</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>         

而在2.x版本中,比如我們需要eureka,去maven倉庫中可能會看到deprecated, please use spring-cloud-starter-netflix-eureka-client這類提示,包括使用ribbon也會有

在這里插入圖片描述
在這里插入圖片描述
2.x版本pom.xml里幾個基本用到的jar長這樣:
        <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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM