03-微服务搭建

1、搭建分布式基本环境

|--------------------------------|----------------------------|
| 分布式组件 | 功能 |
| SpringCloud Alibaba - Nacos | 注册中心(服务发现/注册)、配置中心(动态配置管理) |
| SpringCloud Alibaba - Sentinel | 服务容错(限流、降级、熔断) |
| SpringCloud Alibaba - Seata | 原 Fescar,即分布式事务解决方案 |
| SpringCloud - Ribbon | 负载均衡 |
| SpringCloud - Feign | 声明式 HTTP 客户端(调用远程服务) |
| SpringCloud - Sleuth | 调用链监控 |
| SpringCloud - Gateway | API 网关(webflux 编程模式) |

引入微服务依赖

在 common 模块中引入 springcloud-alibaba 版本依赖

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>2.1.0.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
Nacos 注册中心

首先,修改common模块的 pom.xml 文件,引入 Nacos Discovery Starter。

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

下载启动 nacos:Releases · alibaba/nacos · GitHub,双击 nacos\bin\startup.cmd

每个微服务应用的 /src/main/resources/application.properties 配置文件中配置 Nacos Server 地址

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

每个服务的启动类上添加 @EnableDiscoveryClient 注解开启服务注册与发现功能

@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {

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

    @RestController
    class EchoController {
        @GetMapping(value = "/echo/{string}")
        public String echo(@PathVariable String string) {
            return string;
        }
    }
}

配置每个服务名称

spring.application.name=gulimall-coupon

启动服务,在 nacos 中查看是否注册成功

OpenFeign 远程调用

每个服务引入 openfeign 依赖

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

声明远程调用服务接口:在 member 服务中定义此接口(member 服务调用 coupon 服务),将所有的远程调用接口都放在 feign 包里面。

@FeignClient("gulimail-coupon")
public interface CouponFeignService {
    
    @RequestMapping("coupon/coupon/member/list")
    public R memberCoupons();
}

调用方服务(member)开启远程调用注解:@EnableFeignClients

@EnableFeignClients(basePackages = "com.atguigu.gulimail.member.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallMemberApplication {

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

}

member 服务远程调用 coupon 服务

@Autowired
CouponFeignService couponFeignService;

@RequestMapping("/coupons")
public R test() {
    // 定义一个会员
    MemberEntity memberEntity = new MemberEntity();
    memberEntity.setNickname("龙傲天");
    
    // 远程调用copuon服务获取此会员的优惠卷
    R memberCoupons = couponFeignService.memberCoupons();
    return R.ok().put("member", memberEntity).put("coupons", memberCoupons.get("coupons"));
}

coupon 服务获取优惠卷列表

/*
* 返回当前会员的所有优惠卷
* */
@RequestMapping("/member/list")
public R memeberCoupons() {
    CouponEntity couponEntity = new CouponEntity();
    couponEntity.setCouponName("满100减50...");
    return R.ok().put("coupons", Arrays.asList(couponEntity));
}

访问接口 http://localhost:8000/member/member/coupons 测试远程调用

**注意:**可以访问成功的前提是,服务提前注册到了nacos中


Nacos 配置中心
原始读取配置方式

如下是没有使用Nacos作为配置中心之前,读取配置文件的方式:

第一步:在配置文件中定义变量信息

coupon.user.name=AotianLong
coupon.user.age=18

第二步:将配置文件中的配置读取到类的变量中

@Value("${coupon.user.name}")
private String name;

@Value("${coupon.user.age}")
private Integer age;

@RequestMapping("/test")
public R test() {
    return R.ok().put("name", name).put("age", age);
}
引入配置中心

需求:原始读取配置方式,程序打包部署后不能动态更改信息,此时就需要引入配置中心了

在common模块引入 nacos 配置依赖和bootstrap依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.1.2</version>
</dependency>

在每个服务应用中创建 /src/main/resources/bootstrap.properties 配置文件

# 微服务名称
spring.application.name=gulimall-coupon

# 配置中心 Nacos 地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

在nacos控制台创建项目的配置如文件,编写配置信息:如,gulimall-coupon.properties

在需要读取配置中心数据的类上添加@RefreshScope注解,在变量上添加 @Value注解

// 动态刷新
@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @Value("${coupon.user.name}")
    private String name;

    @Value("${coupon.user.age}")
    private Integer age;

    @RequestMapping("/test")
    public R test() {
        return R.ok().put("name", name).put("age", age);
    }
}

**注意:**如果配置中心 和 微服务项目里面的配置文件同时存在相同的配置信息,那么会优先读取配置中心中的信息。


配置中心概念

命名空间:

利用命名空间做环境隔离(默认空间是 public):开发、测试、生产。

在bootstrap.properties配置文件中指定命名空间。

vb 复制代码
`spring.cloud.nacos.config.namespace=e0ed0744-32c5-4f41-8ace-09b1391fc4a1`

**基于微服务进行隔离:**给每个服务创建自己的命名空间,服务在启动的时候只需要加载自己命名空间下的配置文件。

② 配置集: 所有配置的集合;**配置集ID:**Data ID 类似文件名

**配置分组:**默认所有的配置集都属于 DEFAULT_GROUP,可以配置配置分组

# 在bootstrap.properties 配置文件中指定配置分组。
spring.cloud.nacos.config.group=dev

每个微服务创建自己的命名空间,使用配置分组区分环境(开发、测试、生产...)


拆分配置

需求:同时加载多个配置集,不同组件的配置不会写在同一个配置文件中如:数据源、框架、微服务

配置文件按功能拆分:如spring拆分成一个,mybatis拆分成一个、其他配置再拆分成一个

在bootstrap.properties 配置文件中加载配置信息

spring.cloud.nacos.config.namespace=42917e19-6cbd-4478-89a1-3e36d5d16df5
spring.cloud.nacos.config.group=dev

spring.cloud.nacos.config.ext-config[0].data-id=datasource.yaml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yaml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

spring.cloud.nacos.config.ext-config[2].data-id=others.yaml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

Gateway 网关

网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。

网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的 API,以降低管理成本和安全风险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。

|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| ###### 核心概念 | 解释 |
| 路由 | 路由是网关最基础的部分,路由信息有一个 ID、一个目的 URL、一组断言和一组 Filter 组成。如果断言路由为真,则说明请求的 URL 和配置匹配 |
| 断言 | Java8 中的断言函数。Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配来自于 http request 中的任何信息,比如请求头和参数等。 |
| 过滤器 | 一个标准的 Spring webFilter。Spring cloud gateway 中的 filter 分为两种类型的Filter,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理。 |

创建 gateway 服务,引入gulimail-common依赖

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.8.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-gateway</name>
<description>网关服务</description>

<properties>
  <java.version>1.8</java.version>
  <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway-mvc</artifactId>
  </dependency>
  <!--        引入common依赖(注册中心、配置中心)-->
  <dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>
</dependencies>

开启服务注册发现:@EnableDiscoveryClient ,并排除数据源的配置

@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {

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

}

配置 Nacos 服务地址、服务名和端口:application.properties

spring.application.name=gulimall-gateway
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
server.port=88

配置Naocs配置中心地址、并指定命名空间:bootstrap.properties

spring.cloud.nacos.config.namespace=84f86833-fca4-4ee9-9ffd-fbb65ccaebfb

测试网关服务:在application.yaml 文件中编写路由规则后启动服务

spring:
  cloud:
    gateway:
      routes:
        - id: qq_route
          uri: https://www.qq.com
          predicates:
            - Query=url,qq
相关推荐
程序员老冯头6 分钟前
第三十六章 C++ 多线程
java·c++·信号处理
luochen330x10 分钟前
C++类的引入
java·开发语言
doshy_15 分钟前
aws协议实现文件管理
java·spring boot·aws
命运之手37 分钟前
[ Java ] Install Redis On Mac
java·redis·mac
zuihongyan51839 分钟前
Arthas监控方法内部调用路径,并输出方法路径上的每个节点上耗时
java·arthas·方法耗时监控
xweiran1 小时前
RabbitMQ消费者重试的两种方案
java·rabbitmq·java-rabbitmq·重试·消息消费失败
NullPointerExpection1 小时前
java 中 main 方法使用 KafkaConsumer 拉取 kafka 消息如何禁止输出 debug 日志
java·kafka·log4j·slf4j
一只鹿鹿鹿1 小时前
软件项目体系建设文档,项目开发实施运维,审计,安全体系建设,验收交付,售前资料(word原件)
java·大数据·运维·产品经理·设计规范
Archy_Wang_11 小时前
ASP.NET Core 实现微服务 -- Polly 服务降级熔断
后端·微服务·asp.net
涔溪1 小时前
idea无法使用nodejs
java·ide·intellij-idea