第4章 服务治理与负载均衡

笔者学习SpringCloud所用书籍,京东地址,点我传送~

发现一个问题,在这里先啰嗦几句

笔者发现该书籍《Spring Cloud 微服务架构开发实战》(作者:董超 胡炽维)是2018年8月份初版书籍
书中所用Boot版本为1.5.X,时至今日,Boot版本已经迭代到了2.X,因此在学习的时候,由于笔者使用了新的Boot版本造成Cloud一些子项目比如Eureka依赖的引入,都已经和书籍中有所不同,也算是自己亲自读书,实践的一个印证,先记于此。

另外:文章有点长,因为贴了很多自己写的代码

4.0 引

微服务架构中,我们需要解决的第一个重要场景:
就是让作为消费者的微服务知道服务提供者并能够进行消费
而这个场景的解决方案就是:
服务治理

4.1 什么是服务治理

服务治理通过抽象将福物料费这和服务提供者进行隔离;
消费者不需要知道具体服务提供者的真实物理地址就可以进行调用,也无须知道具体有多少个服务者可用;
服务提供者只需要将自己注册到服务治理服务器中就可以对外提供服务,也不需要知道具体是那些服务调用了自己;

另外
服务治理能够为微服务架构提升应用弹性,当其中一个服务提供者实例不可用或者出现问题时,服务治理服务器可以发现这个有问题的服务实例,在调度服务消费者时可以绕开有问题的服务实例,从而将对应用的影响降低到最低.

4.1.1 基于云的服务治理的优点
  • 高可用

    服务治理可以支持动态的服务实例集群环境,任何服务实例可以随时上线或下线.
    服务消费者只需要知道服务名称就可以调用相应的服务,而不需要具体的物理地址.
    服务提供者的实例信息由服务治理服务器进行统一管理,当一个服务实力不可用时,治理服务器可以将请求转给其他服务提供者,当一个新的服务实例上线时,也能够快速的分担服务调用请求.

  • 负载均衡

    服务治理可以提供动态的负载均衡功能,可以将所有请求动态的分布到其所管理的所有服务实例中进行处理;

  • 提升应用的弹性

    服务治理的客户端会定时从服务治理服务器中复制一份服务实例信息缓存到本地(可配置),这样即使当服务治理服务器不可用时,服务消费者也可以使用本地的缓存去访问相应的服务,而不至于中断服务.

  • 高可用集群

    可以构建服务治理集群,通过互相注册机制,将每个治理服务器所管辖的服务信息列表进行交换,使服务治理服务拥有更高的可用性.

Eureka 是Spring Cloud 的服务治理解决方案
Eureka 对于服务治理有以下几个概念:

  • 服务治理服务器(Eureka服务器): 服务注册中心,负责服务列表的注册,维护和查询等功能,也就是Eureka服务器.
  • 服务注册代理(服务提供者): 如果一个微服务是一个服务提供者, 那么可以通过服务注册代理将服务配置信息注册到治理服务器上. 服务注册代理可以理解为一个Eureka客户端,负责将微服务所提供的的服务向Eureka服务器执行注册,续约和注销等操作, 以使服务消费者可以发现并进行消费. 在服务注册时需要向服务治理服务器提供服务名称, 宿主服务器IP地址,服务端口号,域名等主要数据.
  • 服务发现客户端(服务消费者): 也是一个Eureka客户端. 它在启动时会默认从服务治理服务器中获取所有的服务注册表信息,通过所获取到的服务注册列表信息来消费相应的服务.

4.2 构建服务治理 ---- Eureka

例:
商城, 搭建一个用户微服务和商品微服务,并且搭建一个服务治理服务器(Eureka服务器)
在这里插入图片描述

4.2.1 搭建微服务Parent工程

该工程除了pom.xml之外没有其它的内容

因为该工程的功能就是: 在该pom文件中对所使用的的Spring Cloud 及第三方依赖的版本就行统一管理,当后续需要升级某个第三方依赖时,只需要在该pom.xml文件中同意修改即可.

这里其实用到的是MAVEN 的继承的概念.
下面我们看parent工程pom文件的内容

<?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.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.turnsole.shop-parent</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1</version>
    <name>parent</name>
    <description>parent project for Spring Boot</description>
    <packaging>pom</packaging>
	 <!--这里进行版本的统一管理-->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <guava.version>28.1-jre</guava.version>
        <boot.version>2.1.9.RELEASE</boot.version>
        <HikariCP.version>3.4.1</HikariCP.version>
        <mybatis.version>2.1.0</mybatis.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR3</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <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>

需要注意的是, 这里SpringBoot我使用的版本和书中的版本是不一样的, 书中Boot版本为1.5.2.RELEASE

注意: packaging,打包方式 是 pom

还有一点Spring Boot 和 Spring Cloud 有版本上的严格匹配, 如果不匹配后面项目启动的时候就会失败. 因此下附一个 Boot和Cloud的版本匹配信息

spring-cloud    
Finchley.M2                     "Spring Boot >=2.0.0.M3 and <2.0.0.M5"
Finchley.M3                     "Spring Boot >=2.0.0.M5 and <=2.0.0.M5"
Finchley.M4                     "Spring Boot >=2.0.0.M6 and <=2.0.0.M6"
Finchley.M5    "Spring Boot >=2.0.0.M7 and <=2.0.0.M7"
Finchley.M6    "Spring Boot >=2.0.0.RC1 and <=2.0.0.RC1"
Finchley.M7    "Spring Boot >=2.0.0.RC2 and <=2.0.0.RC2"
Finchley.M9    "Spring Boot >=2.0.0.RELEASE and <=2.0.0.RELEASE"
Finchley.RC1    "Spring Boot >=2.0.1.RELEASE and <2.0.2.RELEASE"
Finchley.RC2    "Spring Boot >=2.0.2.RELEASE and <2.0.3.RELEASE"
Finchley.SR4    "Spring Boot >=2.0.3.RELEASE and <2.0.999.BUILD-SNAPSHOT"
Finchley.BUILD-SNAPSHOT    "Spring Boot >=2.0.999.BUILD-SNAPSHOT and <2.1.0.M3"
Greenwich.M1    "Spring Boot >=2.1.0.M3 and <2.1.0.RELEASE"
Greenwich.SR2    "Spring Boot >=2.1.0.RELEASE and <2.1.9.BUILD-SNAPSHOT"
Greenwich.BUILD-SNAPSHOT    "Spring Boot >=2.1.9.BUILD-SNAPSHOT and <2.2.0.M4"
Hoxton.M2    "Spring Boot >=2.2.0.M4 and <=2.2.0.M5"
Hoxton.BUILD-SNAPSHOT    "Spring Boot >=2.2.0.BUILD-SNAPSHOT"

与其它项目版本匹配信息,烦请查看官方文档

4.2.2 搭建服务治理服务器----Eureka服务器

1. pom.xml

Eureka服务器 server-discovery的POM文件如下:

	<?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>com.turnsole.shop-parent</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1</version>
        <relativePath>../parent</relativePath><!-- lookup parent from repository -->
    </parent>

    <artifactId>server-discovery</artifactId>
    <name>server-discovery</name>
    <description>server-discovery project for Spring Boot</description>

    <dependencies>
        <!--定义对Eureka服务器包的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
    </dependencies>

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

注意:不卖关子,直接说我在学习的时候遇到的问题

eureka治理服务器 server-discovery的pom文件中,在引入Eureka服务器包依赖的时候书中使用的是

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

如果使用上述依赖,启动该项目的时候是会报错的,我们应该使用如下依赖

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

这里版本号需要加上,不然后面在启动类中加入的Eureka注解会无效(我的是这样), 此处我们可以将版本放到parent中统一管理.

2. 应用启动类中需要加入Eureka相关注解

//只需要增加该标签,即可启动Eureka服务器的相关功能,说明该项目是服务治理服务器(Eureka服务器)
@EnableEurekaServer
@SpringBootApplication
public class ServerDiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServerDiscoveryApplication.class, args);
    }
}

3. 项目application.properties

#服务器运行端口
server.port=8260
#Eureka相应配置
#用来控制当Spring Boot启动服务完成后是否将该服务注册到服务治理服务器上
#此时我们本身就是服务治理服务器所以配置false
eureka.client.register-with-eureka=false
#表示应用启动后是否需要从服务治理服务器中同步已注册的服务注册列表数据到本地
eureka.client.fetch-registry=false
#设置eureka.server 同步失败的重试次数 默认5次
eureka.server.wait-time-in-ms-when-sync-empty=5

至此我们的服务治理服务器已经搭建完毕,启动之后,访问 http://localhost:8260就会看到如下界面,一个还没有任何服务注册的服务治理服务器
在这里插入图片描述

4.2.3 搭建服务提供者----注册服务(此注册是指该微服务注册到Eureka治理服务器上)

该服务涉及用户相关业务,思考了3秒钟,决定把全部代码贴出来,所以文章会比较长…

1. pom.xml

<?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>com.turnsole.shop-parent</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

    <artifactId>user-service</artifactId>
    <name>user-service</name>
    <description>user-service project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

        <!--引入web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${boot.version}</version>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>${HikariCP.version}</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--引入mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!--Guava-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--lang3-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!--logback-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <!--validator-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Alpha6</version>
        </dependency>

        <!--jackson-->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
    </dependencies>

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

            <!--mybatis generator plugin-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.17</version>
                    </dependency>
                </dependencies>
                <version>1.3.7</version>
            </plugin>
        </plugins>
    </build>
</project>

注意

  1. 项目中用到了一些在学习Cloud中可有可无的东西,比如参数验证,
  2. 在数据库连接池和dao层的架构选型上做出了和书中不一样的选择, 笔者在此使用的是 HikariCP,mybatis
  3. 另外引入了lombok,logback,以及Guava,这些好用的框架.在项目中除了logback仅仅是引入之外,其它的或多或少的进行了使用.
  4. 引入了mybatis-generator, 代码逆向生成工具.
  5. 关于generatorConfig.xml, logback.xml, mybatis-config.xml,网上有很多啊,大家随便百度/Google都可以找到.就不贴了.

2. 修改应用启动类

/**
 * @EnableDiscoveryClient 表示这是一个Eureka客户端
 * 通过该注解在Spring Boot启动完毕之后,就会根据配置中的信息尝试与服务治理服务器进行连接
 * 连接成功之后进行服务注册或者服务注册信息的同步
 */
@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

注意:

细心的同学会发现,我们此处注入的注解是 @EnableDiscoveryClientserver-discovery中的注解则是@EnableEurekaServer.
@EnableDiscoveryClient表示,这是一个Eureka客户端,通过该注解,在Spring Boot项目启动完毕之后,就会根据配置中的信息尝试与服务治理服务器进行连接, 连接成功之后进行服务注册或者服务注册信息的同步.

3. application.properties

#用户微服务的端口
server.port=2100
#server.servlet.context-path=/user
#用户微服务的应用名/服务ID
spring.application.name=userservice
#Eureka相关配置
#是否需要将微服务所在主机IP注册到治理服务器中
eureka.instance.prefer-ip-address=true
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
# 服务治理服务器的地址
eureka.client.service-url.defaultZone=http://localhost:8260/eureka

#数据库相关配置
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=Xukai1234!@#$
spring.datasource.hikari.maximum-pool-size=200
spring.datasource.hikari.max-lifetime=60000

#mybatis
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath*:com/turnsole/userservice/mapper/*.xml
mybatis.type-aliases-package=com.turnsole.userservice.domain.model

注意,其它的数据库相关,mybatis相关的配置不多说. 一定要注意我们Eureka相关配置中的
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
表示需要将本微服务注册到Eureka服务器中,并且需要从Eureka服务器中同步所有注册服务数据到本地

通常对于Eureka客户端我们都会把这两个属性设置为true,但某些情况下可能需要将某个属性设置为false, 如一个服务实例单纯的作为服务提供者并不消费其他服务,那么就可以将eureka.client.fetch-registry设置为false.

同样,如果一个服务实例仅作为服务消费者而不对外提供服务,那么可以将eureka.client.register-with-eureka设置为false,比如此处,我们的用户微服务不会作为消费者,所以可以将eureka.client.fetch-registry设置为false

4. 其它关于用户微服务的代码

为了不影响整体阅读,现将商品微服务的其它代码单独至于一个文章之中,下附传送门

传送门

至此我们用户微服务已经搭建完成,下面进行测试
先启动之前搭建好的服务治理服务器
再启动用户微服务
启动成功之后,访问http://localhost:8260您会看到如下页面
在这里插入图片描述

您会发现一个名为USERSERVICE 的服务已经注册进来了

这个USERSERVICE对应的就是我们application.properties中配置的微服务的名称(大小写不敏感)

#用户微服务的应用名/服务ID
spring.application.name=userservice

Eureka服务器还提供了一个端点(/eureka/apps/[APPID]) 可以查看所注册的服务详细信息. 我们通过postman访问一波,结果如下:
在这里插入图片描述
注意:
对于每一个需要注册到Eureka服务器的服务,都需要提供以下两个ID

  • application.name: 即应用的ID,用来对服务进行分组。相同的ID表示这些服务实例所提供的服务是相同的。在SpringBoot项目中 我们使用 spring.application.name来进行配置
  • instanceId:也就是微服务实例ID,用来表示每一个注册到Eureka服务器中的服务实例。默认值是:服务宿主机器名称+服务名称+端口号 构成。、

4.2.4 搭建服务消费者----获取服务

我们要求该服务作为服务的消费者和提供者。消费的是用户微服务的服务

1. pom.xml

<?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>com.turnsole.shop-parent</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

    <artifactId>product-service</artifactId>
    <name>product-service</name>
    <description>product-service project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

        <!--引入web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${boot.version}</version>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>${HikariCP.version}</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--引入mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!--Guava-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--lang3-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!--logback-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <!--validator-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Alpha6</version>
        </dependency>

        <!--jackson-->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

    </dependencies>

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

            <!--mybatis generator plugin-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.17</version>
                    </dependency>
                </dependencies>
                <version>1.3.7</version>
            </plugin>
        </plugins>
    </build>
</project>

pom文件内容和用户微服务的相同,但是接口要更改

2. application.properties

#商品微服务的端口
server.port=2200
#商品微服务的应用名/服务ID
spring.application.name=productservice
#Eureka相关配置
eureka.instance.prefer-ip-address=true
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://localhost:8260/eureka

#数据库配置
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shop?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=Xukai1234!@#$
spring.datasource.hikari.maximum-pool-size=200
spring.datasource.hikari.max-lifetime=60000

#mybatis
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath*:com/turnsole/productservice/mapper/*.xml
mybatis.type-aliases-package=com.turnsole.productservice.domain.model

需要注意的是eureka.client.fetch-registry一定要设置为true,因为我们需要使用用户微服务的服务,所以需要在应用启动后,从服务治理服务器中获取已注册的服务列表到本地。不然咋找用户的服务~

3. 应用启动类

@MapperScan("com.turnsole.productservice.mapper")
@EnableDiscoveryClient
@SpringBootApplication
public class ProductServiceApplication {

    //创建一个RestTemplate Bean
    @Bean(value = "restTemplate")
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

我们需要通过 restTemplate 去访问用户微服务,因此在应用启动类中初始化一个restTemplate 的 bean

4. 其它关于用户微服务的代码

为了不影响整体阅读,现将用户微服务的其它代码单独至于一个文章之中,下附传送门

传送门

至此商品微服务已经搭建完成。
我们想要达到的测试效果是,在商品微服务中能够以微服务的形式访问到用户微服务,因此我们在 ProductCommentController中创建了一个接口,通过调用该接口,我们能够查看指定商品的所有评论,商品信息以及评论者的信息

5. 测试

  1. 启动服务治理服务器,启动用户微服务,启动商品微服务 在这里插入图片描述
  2. 启动成功后,借助Postman,访问 商品微服务中的 /{productId}/comments接口,URL为:http://localhost:2200/comment/2/comments
  3. 最终得到结果如下图所示:
    在这里插入图片描述

完成~~~

下面开始进入 负载均衡Ribbon,使用Feign简化微服务调用 的学习阶段!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值