zoukankan      html  css  js  c++  java
  • SpringCloud从入门到进阶(六)——使用SpringBoot搭建微服务

    内容

      SpringBoot整合SpringCloud的Eureka、Zuul等组件,快速实现简单易懂且具有服务熔断、负载均衡的分布式架构1.0,体验微服务的魅力。

    版本

      IDE:IDEA 2017.2.2 x64

      JDK:1.8.0_171

      manve:3.3.3

      SpringBoot:1.5.9.RELEASE

      SpringCloud:Dalston.SR1

    适合人群

      ​Java开发人员

    说明

      转载请说明出处:SpringCloud从入门到进阶(六)——使用SpringBoot搭建微服务

      GitHub仓库地址: https://github.com/leo-zz/SpringCloudDemo/tree/master/MicroServiceDemo

    参考

           Linux入门实践笔记(二)--Jar包运行与关闭

           SpringCloud从入门到进阶(二)——注册中心Eureka的伪分布式部署

    项目目录

    pom.xml

      在原有SpringBoot项目的基础上引入SpringCloud的默认依赖,以及eureka client的依赖

    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.leo</groupId>
        <artifactId>service</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <!-- 通过继承的方式引入spring boot  -->
        <!--parent标签用于指定父pom-->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.RELEASE</version>
        </parent>
    
        <!--properties标签用于声明一些常量,例如源码编码为UTF-8,输出代码也为UTF-8,Java版本为1.8-->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Dalston.SR1</spring-cloud.version>
        </properties>
    
        <!--添加1:在dependencyManagement标签中声明默认依赖的SpringCloud的版本,
        所有的SpringCloud组件的依赖都将使用该版本SpringCloud中规定的版本号 -->
        <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>
    
        <dependencies>
            <!--添加2:SpringCloud-Eureka相关依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <!-- SpringBoot相关等其他依赖省略 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    
        <!-- Spring Boot的Maven插件,使用Maven插件的方式来启动Spring Boot工程
    如果不添加该插件在使用mvn命令打包的jar有问题,执行时会报错:xxx.jar中没有主清单属性-->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    yaml

      在原有项目的基础上增加eurekaSever的连接信息、微服务的应用名称、多profiles的配置。为了演示负载均衡的效果,本示例添加三个profiles。

    spring:
      #添加3:设置springboot项目的应用名称,并默认启动peer1
      application:
        name: application-serviceA    #注意:此处的名称一定要个路由接入服务器中的配置名一致 
      profiles: 
          active: peer1
      http:
        multipart:
          #上传文件总的最大值为30MB
          max-request-size: 30MB
          #单个文件的最大值为10MB
          max-file-size: 10MB
        #省略原有Springboot项目的数据源、redis、mybatis、分页等配置
        
    #添加4:eurekaSever的连接信息
    eureka:
      instance: 
        #要求Client通过ip的方式进行注册
        prefer-ip-address: true
      client:
        service-url:
          defaultZone: http://172.26.125.114:7001/eureka,http://172.26.125.115:7001/eureka,http://172.26.125.118:7001/eureka
      
    #日志输出,指明日志存放位置;同时需要在资源路径下引入配置文件
    logging:
      file: logs/application-idleGoodService-${server.port}.logs
    
    #添加5:增加peer1和peer2、peer3多个profiles的配置
    ---
    spring:
      profiles: peer1
    server:
      port: 8881
    
    #Eureka实例名的配置
    eureka:
      instance:
        instance-id: application-serviceA-A2-8881
    
    #actuator的配置
    management:
      port: 8811
      security:
        enabled: false
    
    ---
    spring:
      profiles: peer2
    server:
      port: 8882
    
    #Eureka实例名的配置
    eureka:
      instance:
        instance-id: application-serviceA-A2-8882
    
    #actuator的配置
    management:
      port: 8812
      security:
        enabled: false
    ---
    spring:
      profiles: peer3
    server:
      port: 8883
    
    #Eureka实例名的配置
    eureka:
      instance:
        instance-id: application-serviceA-A2-8883
    
    #actuator的配置
    management:
      port: 8813
      security:
        enabled: false
    SpringApplication

      在主程序类中增加@EurekaClient,开启eureka服务。

    //开启EurekaClient
    @EnableEurekaClient
    @SpringBootApplication
    //包扫描、Swagger、事务的配置省略
    public class IdlegoodApplication {
    ​
        //一些bean的注入和创建省略public static void main(String[] args) {
            SpringApplication.run(IdlegoodApplication.class, args);
        }
    }
    Controller

      SpringBoot项目改造成微服务时,业务逻辑只要保证无状态即可,不要进行额外配置。本示例为了演示功能,在Controller中写两个服务,一个是普通POST接口处理,一个是文件上传的接口。

    @RequestMapping("/test")
    @RestController
    public class DemoController {
        //从配置文件中读取实例名称
        @Value("${eureka.instance.instance-id}")
        String instanceID;
    
        @PostMapping("/hello/{name}")
        public String sayHello(@PathVariable(value = "name") String name,
                               @RequestParam(value = "from") String user){
            return "Hello "+name+",this is DemoTest.From "+user+"@:"+instanceID+".";
        }
        @PostMapping("/upload")
        public String uploadFile(@RequestParam("file") MultipartFile file){
            String str="file名称:"+file.getOriginalFilename()+",file大小:"+file.getSize()+"From "+instanceID+".";
            System.out.println(str);
            return str;
        }
    }

    本地测试

      在本地以默认的profiles启动项目,然后使用postman请求这两个接口,确保项目代码编写正常。

      ​测试接口1:http://localhost:8881/test/hello/leo,正常。

      测试接口2:http://localhost:8881/test/upload,向服务器上传大于1MB的文件,正常。

    直接调用微服务测试

      按照之前的操作进行项目打包、上传,具体过程可参考:SpringCloud从入门到进阶(二)——注册中心Eureka的伪分布式部署

    ​   先启动Eureka集群和路由Zuul,然后在同一个局域网内的主机上,分别执行下列命令启动微服务的三个实例。启动后可以通过jps命令可以看到相应的进程:

    [user@Serverjars]$java -Dspring.profiles.active=peer1 -jar service-1.0-SNAPSHOT.jar & #服务器A
    [user@Serverjars]$java -Dspring.profiles.active=peer2 -jar service-1.0-SNAPSHOT.jar & #服务器B
    [user@Serverjars]$java -Dspring.profiles.active=peer3 -jar service-1.0-SNAPSHOT.jar & #服务器B
    #通过jps命令可以看到相应的进程,-v选型表示打印jvm参数。
    [user@Serverjars]$ jps -v
    29410 jar -Dspring.profiles.active=peer1
    29366 jar -Dspring.profiles.active=peer2
    29321 jar -Dspring.profiles.active=peer3

      访问EurekaSever,确认服务正常启动。

      与本地测试一样,直接调用微服务的接口地址,进行测试。假如主机的IP为172.26.125.10,那么分别请求http://172.26.125.10:8881/test/hello/leohttp://172.26.125.10:8882/test/hello/leohttp://172.26.125.10:8883/test/hello/leo等地址,以确保微服务部署正确。

    通过路由调用微服务测试

      确保微服务部署正确无误后再使用Postman请求路由接入服务器的接口。假如路由Zuul所在主机的IP为172.26.125.20,那么请求接口1http://172.26.125.20:7081/v1/routea/test/hello/leo和接口2http://172.26.125.20:7081/v1/routea/test/upload。Zuul在接收到该url的请求时,会根据路由规则的设定,将"/v1/routea/**"的请求转发给application-serviceA处理。

    测试接口1

      ​测试多次,可以看到Zuul会将请求在多个微服务实例中做负载均衡,默认情况按照轮询算法分配请求。

      请求转发到实例1处理:

      请求转发到实例2处理:

      请求转发到实例3处理:

    测试接口2

    ​  向服务器上传小于1MB的文件,测试多次,也可以看到负载均衡的效果。

      请求转发到实例1处理:

      请求转发到实例2处理:

      请求转发到实例3处理:

       但是,当上传超过1MB大小的文件时,服务报错。

      出现这个问题,想必大家都有疑问。同样的请求,为什么直接调用服务时正常,但是通过Zuul路由调用服务就会出错呢。如果你在上传文件的测试中,还遇到服务调用失败、中文乱码等诡异报错,那么说明你测得很全面。对于这些问题的解释和解决,请看下篇文章[SpringCloud从入门到进阶(七)——踩坑实战之Zuul服务调用失败与文件上传问题](https://www.cnblogs.com/lonelyJay/p/9994246.html)

    补充:使用Zipkin监控路由Zuul的请求处理。

      为了监控请求处理的耗时情况,会在路由端和微服务端增加链路追踪组件Zipkin,具体配置请参考后续章节。

  • 相关阅读:
    PHP preg_replace_callback_array() 函数
    PHP preg_quote() 函数
    PHP preg_match() 函数
    SqlHelper工具类
    ArrayListd的长度问题
    事务
    Socket通信
    时间戳,产生随机数
    背景大小 | background-size (Backgrounds & Borders)
    背景图片位置 | background-position (Backgrounds & Borders)
  • 原文地址:https://www.cnblogs.com/lonelyJay/p/9842175.html
Copyright © 2011-2022 走看看