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,具体配置请参考后续章节。

  • 相关阅读:
    【leetcode】1630. Arithmetic Subarrays
    【leetcode】1629. Slowest Key
    【leetcode】1624. Largest Substring Between Two Equal Characters
    【leetcode】1620. Coordinate With Maximum Network Quality
    【leetcode】1619. Mean of Array After Removing Some Elements
    【leetcode】1609. Even Odd Tree
    【leetcode】1608. Special Array With X Elements Greater Than or Equal X
    【leetcode】1603. Design Parking System
    【leetcode】1598. Crawler Log Folder
    Java基础加强总结(三)——代理(Proxy)Java实现Ip代理池
  • 原文地址:https://www.cnblogs.com/lonelyJay/p/9842175.html
Copyright © 2011-2022 走看看