微服务实践(四)商品模块搭建

一、创建多模块Maven SpringBoot项目

1.新建SpringBoot项目,直接选择Next下一步

2.在建立好的父结构上选择 New →Module→选择Maven项目

3.选择依赖父Pom

4.继续建立一个api模块,提供Feign接口供外部调用

5.最终的项目结构,父Pom的src目录用不着,可以直接删了

6.在父Pom (product-center.pom)中引入相关依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>

  <properties>
        <spring.boot.version>2.3.3.RELEASE</spring.boot.version>
        <mybatis.plus.version>3.3.2</mybatis.plus.version>
    </properties>

    <dependencyManagement>
        <dependencies>

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

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

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

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.plus.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

7.在server模块中新建包并添加启动类ProductApplication

8.在resources目录下新建配置文件

bootstrap.yaml

配置一些引导系统启动的参数,这些参数一旦指定后就不会变动了。比如程序的端口号,配置中心的地址等。

application.yaml

应用级别的参数配置,可能会根据业务需求做动态配置。比如日志级别,一些开关参数等。

9.在bootstrap.yml添加配置:

spring:
  application:
    name: product-center-server
server:
  port: 8092

10.在application.yml添加数据库配置:

spring:
  datasource:
    username: 你的用户名
    password: 你的密码
    url: jdbc:mysql://localhost:3306/local?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver‐class‐name: com.mysql.jdbc.Driver

11.添加好配置后就可以正常启动应用了。

二、集成SpringCloud
集成Nacos

1.在父pom(product-center.pom)声明依赖及版本:

    <dependencyManagement>  
...
 <!--注册中心需要的依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>${spring-cloud-nacos.version}</version>
            </dependency>

            <!--配置中心需要的依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
                <version>${spring-cloud-nacos.version}</version>
            </dependency>
            <!--openfeign需要的依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>${spring-cloud-starter-feign.version}</version>
            </dependency>
...
 </dependencyManagement>

2.指定依赖版本属性

  <spring-cloud-nacos.version>2.2.0.RELEASE</spring-cloud-nacos.version>
  <spring-cloud-starter-feign.version>2.2.0.RELEASE</spring-cloud-starter-feign.version>

3.在子pom(product-center-server.xml)添加 dependency依赖:

	<!--注册中心需要的依赖-->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
		</dependency>

		<!--配置中心需要的依赖-->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
		</dependency>

注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。

更多版本对应关系参考:版本说明 Wiki

4.在 bootstrap.yml中配置 Nacos server 的地址和应用名

spring:
  application:
    name: product-center-server
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        namespace: a506f87b-88c7-4fb9-bea4-c59881e140e8  
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: a506f87b-88c7-4fb9-bea4-c59881e140e8
server:
  port: 8092

namespace、group不填默认为 public 和DEFAULT_GROUP,这里namespace填上 local对应的namespace ID。 添加好依赖和配置后在应用上添加注解@EnableDiscoveryClient开启服务注册发现功能

@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication {

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

5.启动应用,可以看到打印的注册信息。

6.可以看到注册成功,接下来为商品服务新建一条配置信息内容如下:

7.配置内容目前只添加了数据库信息,可根据自己业务需求添加对应的配置。

8.通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${testConfig}")
    private String useLocalCache;

    @RequestMapping("/get")
    public String get() {
        return useLocalCache;
    }
}

9.访问http://localhost:8091/config/get 可以看到配置进行了刷新。

集成OpenFeign

1.在product-center-api.pom中引入声明的openfeign依赖

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

2.然后新建ProductFeign类,接口跟controller层保持一致,

@FeignClient(contextId = "product",name = "product-center-server")
public interface ProductFeign {

    @GetMapping("/product/detail")
    ResponseResult<ProductResDTO> getById(@RequestParam("id") Long id);

    @PostMapping("/product/delete")
    ResponseResult<Void> getById(@RequestBody BaseIdReq req);
}

3.定义好Feign接口后,客户端就可以引用依赖进行调用了,需要在调用的客户端应用加上@EnableFeignClients注解进行启用。

@FeignClient 常用属性

属性描述
name/value填写应用名称,用于服务发现,与nacos对应的application.name一致。
urlurl一般用于调试,可以手动指定@FeignClient调用的地址
decode404当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
configurationFeign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
fallback定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
fallbackFactory熔断机制,调用失败时,走的一些回退方法,可以用来抛出异常或给出默认返回数据。
底层依赖hystrix,启动类要加上@EnableHystrix
path定义当前FeignClient的统一前缀
集成Hystrix

Hystrix 是一个开源的容错框架,它可以在分布式系统中提供弹性和可靠性,可以帮助我们构建更加健壮的分布式系统。主要功能为熔断(break)和降级(fallback)

降级(fallback)

1.新建降级工厂类,实现FallbackFactory,并覆写降级的时候接口返回的逻辑。

@Component
public class ProductFallbackFactory implements FallbackFactory<ProductFeign> {
    @Override
    public ProductFeign create(Throwable throwable) {
        return new ProductFeign(){

            @Override
            public ResponseResult<ProductResDTO> getById(Long id) {
                ResponseResult result=new ResponseResult();
                result.setCode("000");
                result.setMsg("请稍后重试");
                return result;
            }

            @Override
            public ResponseResult<Void> deleteById(BaseIdReq req) {
                ResponseResult result=new ResponseResult();
                result.setCode("000");
                result.setMsg("请稍后重试");
                return result;
            }
        };
    }
}

2.在ProductFeign上添加fallbackFactory = ProductFallbackFactory.class指定降级工厂。

@FeignClient(contextId = "product",name = "product-center-server",fallbackFactory = ProductFallbackFactory.class)
public interface ProductFeign{
..//省略代码
}

3.如果项目中使用的 Spring Cloud 版本为 Greenwich 及之后的版本,OpenFeign 的 Hystrix 默认是开启的,不需要额外配置,如果使用的是 Greenwich 以前的版本,需要在客户端(也就是调用方)配置文件中添加以下配置开启:

feign:
  hystrix:
    enabled: true

熔断(break

熔断是指当服务出现故障或异常时,保护客户端和服务器不会因为异常的情况导致更多的资源浪费。例如,当一个服务的响应时间超过某个阈值时,熔断器会打开,停止对该服务的请求,直到服务恢复正常。

1.在 pom.xml 文件中添加 的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>{version}</version>
</dependency>

2.配置Hystrix熔断策略:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 设置超时时间
      circuitBreaker:
        enabled: true # 开启熔断
        requestVolumeThreshold: 10 # 熔断请求阈值
        errorThresholdPercentage: 60 # 错误率阈值
        sleepWindowInMilliseconds: 5000 # 熔断器开启时间

3.上述配置当 Hystrix 接收到的请求达到 10 个时,会开始监控请求的错误率,如果错误率超过了 60%,就会触发熔断器开启。在熔断器开启的状态下,所有请求都会被拒绝,直到熔断器开启时间达到设定的 5000 毫秒后,熔断器才会进入半开启状态,允许一定数量的请求通过,以测试服务的可用性。如果测试成功,则熔断器会关闭,否则会重新开启。同时,每个请求的执行时间都不能超过 3000 毫秒,否则会触发超时异常。

注意:Hystrix相关依赖和配置写在调用方,它是用于熔断和降级的功能,这些功能通常是由调用方控制和触发的。被调用方可能没有意识到是否需要熔断或降级