• 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>
  • 相关阅读:
    【Hadoop】HDFS笔记(一):Hadoop的RPC机制
    英文分句
    破解google翻译API全过程
    最大匹配算法 (Maximum Matching)
    【Html 学习笔记】第八节——表单实践
    【Html 学习笔记】第七节——表单
    【Html 学习笔记】第六节——列表
    Linux下第一次Node尝试
    【Html 学习笔记】第五节——表格
    C++并发低级接口:std::thread和std::promise
  • 原文地址:https://www.cnblogs.com/denghy-301/p/13093154.html
Copyright © 2020-2023  润新知