第5天-微服务环境搭建(注册中心、配置中心、网关、远程调用测试)

1.Spring Cloud Alibaba


1.1.Spring Cloud Alibaba 简介

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必
需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里
分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

Guthub:https://github.com/alibaba/spring-cloud-alibaba

1.2.Spring Cloud 几大痛点

  • Spring Cloud 部分组件停止维护和更新,给开发带来不便
  • Spring Cloud 部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
  • Spring Cloud 配置复杂,难以上手,部分配置差别难以区分和合理应用

1.3.Spring Cloud Alibaba 优势

阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用成套的产品搭配完善的可视
化界面给开发运维带来极大的便利,搭建简单,学习曲线低。

1.4.Spring Cloud Alibaba 组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud ACM:一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。

Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可
靠、高可用的定时(基于 Cron 表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。


2.微服务技术选型方案


2.1.技术选型

结合Spring Cloud Alibaba 我们最终的技术选型方案

  • Spring Cloud Alibaba - Nacos:注册中心(服务发现/注册)
  • Spring Cloud Alibaba - Nacos:配置中心(动态配置管理)
  • Spring Cloud Alibaba - Sentinel:服务容错(限流、降级、熔断)
  • Spring Cloud Alibaba - Seata:源Fescar,即分布式事务解决方案
  • Spring Cloud Alibaba - OSS:云对象存储
  • Spring Cloud - Ribbon:负载均衡
  • Spring Cloud - Feign:声明式HTTP客户端(调用远程服务)
  • Spring Cloud - Gateway:API网关(WebFlux编程模式)
  • Spring Cloud - Sleuth:调用链监控

2.2.版本选择

版本选择规约:基于Spring Cloud Alibaba 的发布版本来匹配

spring-cloud-alibaba:https://github.com/alibaba/spring-cloud-alibaba/releases

  • Spring Cloud Alibaba:2.2.3.RELEASE
  • Spring Cloud:Hoxton.SR8
  • Spring Boot:2.3.7.RELEASE在这里插入图片描述

2.3.项目依赖

引入依赖,在公共模块 gmall-common 中引入

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
 </dependencyManagement>

3.微服务环境搭建

                         微服务-注册中心、配置中心、网关

在这里插入图片描述



3.1.Nacos-注册中心


3.1.1.Nacos简介

Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。是构
建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。使用Java编写,需
要依赖Java环境。

官网地址:https://nacos.io/zh-cn/

Nacos 架构
在这里插入图片描述

3.1.2.Docker安装Nacos

  • docker-compose (容器编排方式)
  • docker run(独立安装方式)

Nacos模式

  • 单机模式 Derby
  • 单机模式 MySQL
  • 集群模式

我们这里使用 单机模式 MySQL 以独立安装方式进行安装,项目部署阶段采用 Kubernetes 进行部署。

安装步骤:

1)创建MySQL数据库

创建数据库 nacos_config ,并执行 nacos-db.sql 脚本

https://github.com/alibaba/nacos/blob/master/config/src/main/resources/META-INF/nacos-db.sql

 /*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `c_desc` varchar(256) DEFAULT NULL,
  `c_use` varchar(64) DEFAULT NULL,
  `effect` varchar(64) DEFAULT NULL,
  `type` varchar(64) DEFAULT NULL,
  `c_schema` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT '内容',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `src_user` text,
  `src_ip` varchar(20) DEFAULT NULL,
  `op_type` char(10) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`nid`),
  KEY `idx_gmt_create` (`gmt_create`),
  KEY `idx_gmt_modified` (`gmt_modified`),
  KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL COMMENT 'kp',
  `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
  `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
  `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
  `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

CREATE TABLE users (
	username varchar(50) NOT NULL PRIMARY KEY,
	password varchar(500) NOT NULL,
	enabled boolean NOT NULL
);

CREATE TABLE roles (
	username varchar(50) NOT NULL,
	role varchar(50) NOT NULL,
	constraint uk_username_role UNIQUE (username,role)
);

CREATE TABLE permissions (
    role varchar(50) NOT NULL,
    resource varchar(512) NOT NULL,
    action varchar(8) NOT NULL,
    constraint uk_role_permission UNIQUE (role,resource,action)
);

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

2)从 docker hub 拉取 nacos 镜像

docker pull nacos/nacos-server

3)运行容器

docker run -d \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.0.2 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-v /mydata/nacos/logs:/home/nacos/logs \
-p 8848:8848 \
--restart=always \
--name nacos \
nacos/nacos-server

MYSQL_SERVICE_HOST 是mysql容器的ip
查询方式:docker inspect mysql | grep IPAddress

注意:Nacos 连接不上
- 主要问题是数据库连接问题

docker run -d 
  -e HOST=mysql数据库容器ip地址
  nacos/nacos-server

创建固定ip容器
1、创建自定义网络类型,并且指定网段
sudo docker network create --subnet=192.168.0.0/24 staticnet
  通过docker network ls可以查看到网络类型中多了一个staticnet

2、使用新的网络类型创建并启动容器
sudo docker run -it --name userserver 
      --net staticnet 
      --ip 192.168.0.2 
      ubuntu /bin/bash
  通过docker inspect可以查看容器ip为192.168.0.2,
  关闭容器并重启,发现容器ip并未发生改变


3.1.3.访问Nacos控制台

访问:http://172.168.56.10:8848/nacos

使用默认的 nacos/nacos 进行登录
在这里插入图片描述

登录成功,如下图:

在这里插入图片描述


3.1.4.将微服务注册到Nacos中

官方示例:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-exa
mples/nacos-example/nacos-discovery-example/readme-zh.md


1)引入 nacos discovery starter,将依赖配置到 gmall-common 公共服务模块中

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

2)配置 Nacos Server 地址(服务注册中心地址)

gmall-coupon 配置文件 application.yml 中配置

spring:
	application:
    	name: gmall-coupon
  	cloud:
    	nacos:
      		discovery:
        		server-addr: 192.168.56.10:8848  

3)使用 @EnableDiscoveryClient 开启服务注册发现功能

gmall-coupon 启动类上开启服务发现 @EnableDiscoveryClient

@EnableDiscoveryClient
@SpringBootApplication
public class GmallCouponApplication {
	public static void main(String[] args) {
		SpringApplication.run(GmallCouponApplication.class, args);
	}
}

最新的版本不开启服务注册 @EnableDiscoveryClient ,也能成功注册,为了向下兼容性还是建议
加上

4)启动应用,查看nacos服务列表中是否已经注册上服务

在这里插入图片描述

注意:每一个应用都要有名字,这样才能注册上去,在 application.yml 中配置

spring:
	application:
		name: gmall-coupon

5)按照第2,3,4步骤依次把其它的微服务都注册到Nacos注册中心。



3.2.Feign声明式远程调用


3.2.1.Feign简介

Feign是一个声明式的 HTTP 客户端,它的目的就是让远程调用更加简单。Feign提供了HTTP请求的模
板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。

Feign整合了Ribbon(负载均衡)和Hystrix(服务熔断),可以让我们不再需要显示地使用这两个组
件。

Spring Cloud Feign在Netflix Feign的基础上扩展了Spring MVC注解的支持,在其实现下,我们只需要创
建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了Spring Cloud Ribbon
自行封装服务调用客户端的开发量。

3.2.2. Spring Cloud - Open Feign 远程调用

会员服务 调用 优惠券服务 为例,来测试 Feign 远程调用

1)在会员服务模块 gmall-member 引入 openfeign 依赖

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

2)声明远程调用接口 CouponFeignService

package com.atguigu.gmall.member.feign;

import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Description: gomall-coupon 远程服务接口
 * @Auther: zhangwen
 * @Date: 2023-02-07 20:40
 * @version: 1.0
 */
@FeignClient("gmall-coupon")
public interface CouponFeignService {
    /**
     * 调用 gmall-coupon 远程服务的接口
     * 直接拷贝 gmall-coupon 服务上的方法签名
     */
    @RequestMapping("/coupon/coupon/info/{id}")
    public R info(@PathVariable("id") Long id);
}

3)在主启动类上开启Feign远程调用功能

package com.atguigu.gmall.member;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

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

}

4)编写测试方法

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Autowired
    private CouponFeignService couponFeignService;

    /**
     * 测试 Feign远程调用
     * @return
     */
     @RequestMapping("/testCouponFeign")
     public R testCouponFeign () {
        return couponFeignService.info(1L);
     }

5)启动 nacos-server 和 两个服务(gmall-coupon、gmall-member)

gmall-coupon、gmall-member 这两个服务要在 Nacos 注册中心

在这里插入图片描述

6)Postman进行接口调用测试

访问:http://localhost:6000/member/member/testCouponFeign

在这里插入图片描述


3.2.3.调用流程分析

  1. 构造请求数据,将对象转换为JSON
  2. 发送请求进行执行,执行成功后会解码响应数据
  3. 执行请求会有重试机制
final class SynchronousMethodHandler implements MethodHandler {
	@Override
	public Object invoke(Object[] argv) throws Throwable {
		//构造请求数据,将对象转换为json
		RequestTemplate template = buildTemplateFromArgs.create(argv);
		Options options = findOptions(argv);
		Retryer retryer = this.retryer.clone();
		while (true) {
			try {
			//发送请求进行执行,执行成功后会解码响应数据
				return executeAndDecode(template, options);
			} catch (RetryableException e) {
			  try {
				//执行请求会有重试机制
				retryer.continueOrPropagate(e);
			  } catch (RetryableException th) {
				Throwable cause = th.getCause();
				if (propagationPolicy == UNWRAP && cause ≠ null) {
					throw cause;
				} else {
				  throw th;
				}
			  }
			  if (logLevel ≠ Logger.Level.NONE) {
				logger.logRetry(metadata.configKey(), logLevel);
			  }
				continue;
			}
		}
	}
}

3.3.Nacos - 配置中心

官方示例:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-exa
mples/nacos-example/nacos-config-example/readme-zh.md


3.3.1.引入依赖

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

3.3.2.Nacos配置文件

  • bootstrap.properties
  • bootstrap.yml

gmall-coupon /src/main/resources/bootstrap.properties 配置文件中配置 Nacos Config 元数据

bootstrap.properties 加载优先于 application.properties

# 应用名
spring.application.name=gmall-coupon
# Nacos 配置中心地址
spring.cloud.nacos.config.server-addr=192.168.56.10:8848
spring.cloud.nacos.config.namespace=ff13b57c-f3ed-453c-bb17-058e70747779

3.3.3.添加 @RefreshScope

使用 @Value 将配置注入到 Controller 的 name 和 url 字段,并添加 @RefreshScope 打开动态刷新
功能

@RefreshScope //打开动态刷新功能
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {

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

    /**
     * 测试动态配置功能
     * @return
     */
     @RequestMapping("/testConfig")
     public R testConfig () {
        return R.ok().put("name", name).put("age", age);
     }
}     

3.3.4.启动Nacos Server并添加配置

在Nacos配置中心控制台添加配置gmall-coupon.properties

coupon.user.name=zhangwen
coupon.user.age=30


在这里插入图片描述


在这里插入图片描述



3.3.5.启动测试

启动 gmall-coupon ,访问:http://localhost:5000/coupon/coupon/testConfig

在这里插入图片描述

3.3.6.测试动态刷新

在Nacos控制台,编辑配置,修改 gmall-coupon.properties 配置参数

coupon.user.name=zhangwen123
coupon.user.age=30

无需重启服务,再次发送请求,查看响应结果

在这里插入图片描述

如果配置中心和当前应用的配置文件中都配置了相同的配置项,则优先使用配置中心的配置项


3.4.Nacos配置中心高级


3.4.1.核心概念

  • 命名空间(重要)

    用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data Id 的配
    置。Namespace的常用场景之一是不同环境的配置的区分隔离,例如开发环境和生产环境的
    资源(如配置、服务)隔离等。

    public 保留空间/默认空间,默认新增的所有配置都在public空间

在这里插入图片描述

创建好 devtestprop 三个命名空间,分别对应开发,测试,生产三个环境。


在这里插入图片描述

命名空间创建规则:
1)基于应用环境来进行配置隔离
2)基于服务进行配置隔离
3)…

克隆配置到 dev 命名空间

在这里插入图片描述
在这里插入图片描述

可以在 bootstrap.properties 配置文件中指明使用哪个命名空间,如不指定namespace ,则默认加载 public 默认空间。

#命名空间的为唯一ID
spring.cloud.nacos.config.namespace=10a78493-fbe7-40ef-9bfa-2ad10541dae2
  • 配置集

    一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置
    集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等
    配置项。

  • 配置集ID(Data Id),类似配置文件名

    Nacos中的某个配置集的ID。配置集ID是组织划分配置的维度之一。 Data Id 通常用于组织
    划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义
    的名称标识。 Data Id 通常采用类 Java 包的命名规则保证全局唯一性。此命名规则非强
    制。

  • 配置分组(重要)

    Nacos中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串对配置集进行分
    组,从而区分Data Id相同的配置集。当在Nacos上创建一个配置时,如果未填写配置分组的
    名称,则配置分组的名称默认采用 DEFAULT_GROUP

    DEFAULT_GROUP 默认配置分组

    bootstrap.properties 配置文件中指明使用哪个配置分组

	# 双11配置分组
	spring.cloud.nacos.config.group=1111

3.4.2.同时加载多个配置集

Nacos 配置中心还支持将一个配置集分解为多个配置集,应用启动时可以同时加载

gmall-couponapplication.yml 配置抽取到配置中心 coupon 命名空间

  • datasource.yml

    Data ID:datasource.yml
    Group:dev

  • mybatis.yml:

    Data ID:mybatis.yml
    Group:dev

  • other.yml

    Data ID:other.yml
    Group:dev

gmall-coupon 服务配置 bootstrap.properties 中加入以下配置

#数据源配置
#配置集ID
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
#配置分组
spring.cloud.nacos.config.ext-config[0].group=dev
#动态刷新,默认false
spring.cloud.nacos.config.ext-config[0].refresh=true

#第三方框架配置
spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
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=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

3.4.3.微服务配置中心最佳实践

  • 每个微服务创建自己的命名空间

  • 使用配置分组区分环境:dev、test、prod

  • 微服务任何配置信息,任何配置文件都可以放在配置中心

    1、只需要在 bootstrap.properties 说明加载配置中心中哪些配置文件即可

    2、@Value,@ConfigurationProperties…等从配置文件中获取值的方式都能使用

    3、配置中心有的配置优先使用

  • 开发环境为了开发方便,可以使用本地的配置方式

  • 生产环境都需要将本地配置文件配置到配置中心,只保留 bootstrap.properties 配置文件


3.5.搭建网关服务


3.5.1.简介

网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而Spring Cloud Gateway 作为
Spring Cloud 官方推出的第二代网关框架,取代了 Zuul 网关。

官方文档:https://spring.io/projects/spring-cloud-gateway#overview

在这里插入图片描述

3.5.2.核心概念

  • Route(路由): The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a
    collection of filters. A route is matched if the aggregate predicate
    is true.
  • Predicate(断言): This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange . This lets you match on
    anything from the HTTP request, such as headers or parameters.
  • Filter(过滤器): These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory.
    Here, you can modify requests and responses before or after sending
    the downstream request.

3.5.3.工作流程

在这里插入图片描述

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed.Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.

URIs defined in routes without a port get default port values of 80 and 443 for the HTTP and HTTPS URIs, respectively.

核心流程:当请求到达网关,网关先利用断言来判定这次请求是不是符合某个路由规则,如果符合,则
按照符合的路由规则路由到指定的服务,但在路由到服务之前会经过一些列的过滤器(包括预过滤器和
代理过滤器),服务处理完成后再原路返回响应到客户端。

3.5.4. Route Predicate Factories

官方文档:Route Predicate Factories

基本使用示例:

spring:
	 cloud:
		gateway:
			routes:
			- id: after_route
			uri: https://example.org
			predicates:
			- After=2017-01-20T17:42:47.789-07:00[America/Denver]

This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver).

任何请求到达网关,先断言请求的时间是不是在指定的时间之后,满足条件后就路由到指定的uri.



3.5.5.创建网关服务

1)创建 Module 模块 gmall-gateway

在这里插入图片描述

引入 Gateway 依赖

在这里插入图片描述


修改 gmall-gateway 服务的 pom 文件

  • 修改 Spring BootSpring Cloud 版本号
  • 引入公共服务 gmall-common

2)网关 - Nacos 注册中心

Nacos上创建好网关服务命名空间

在这里插入图片描述

修改 application.yml 配置文件

server:
	port: 90
spring:
	cloud:
		nacos:
			discovery:
				server-addr: 192.168.56.10:8848
				namespace: 28112a82-bf41-4b25-b891-2ca087fdfe06		
	application:
		name: gmall-gateway

在主启动类上开启服务注册与发现功能 @EnableDiscoveryClient.

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

3)排除 gmall-common 公共服务的数据源依赖包

注意:由于 gmall-gateway 网关服务引入了 gmall-common 公共服务模块,没有配置数据源相
关参数,启动会报错,所以需要排除数据源相关信息。

  • 在主启动类上使用 exclude 参数进行排除
//排除数据源相关的信息
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class GmallGatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(GmallGatewayApplication.class, args);
	}
}
  • 在引入 gmall-common 依赖时使用 exclusions 移除包的引用
<dependency>
	<groupId>com.atguigu.gmall</groupId>
	<artifactId>gmall-common</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<!-- 移除数据源相关的依赖 -->
	<exclusions>
		<exclusion>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
		</exclusion>
		<exclusion>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</exclusion>
	</exclusions>
</dependency>

4)启动网关服务,查看Nacos服务列表中是否已经注册 gmall-gateway
在这里插入图片描述


3.5.6.网关路由功能

1)在Nacos配置中心新增网关配置

![在这里插入图片描述](https://img-blog.csdnimg.cn/8f5673facffc47c7af9848c12bfeada1.png

2)网关配置文件 bootstrap.yml

在 gmall-gateway 创建 bootstrap.yml 文件,网关服务启动从 Nacos 配置中心读取配置

spring.application.name=gmall-gateway
spring.cloud.nacos.config.server-addr=192.168.56.10:8848
spring.cloud.nacos.config.namespace=28112a82-bf41-4b25-b891-2ca087fdfe06
spring.cloud.nacos.config.group=dev

3)测试网关路由功能

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个开源的微服务框架,它提供了一系列的工具和组件,用于构建分布式系统中的各个微服务。其中包括服务注册与发现、配置中心网关和服务调用等功能。 服务注册与发现是Spring Cloud中的一个重要组件,它使用Eureka作为服务注册中心。通过在微服务中引入依赖org.springframework.cloud:spring-cloud-starter-eureka,可以实现将微服务注册到Eureka服务器上。\[1\] 配置中心是用于集中管理微服务的配置信息的组件。在Spring Cloud中,可以使用Spring Cloud Config来实现配置中心的功能。通过在微服务中引入依赖org.springframework.cloud:spring-cloud-starter-config,可以将配置信息存储在配置中心,并在微服务启动时从配置中心获取配置信息。 Zuul是Spring Cloud中的网关组件,它可以实现请求的路由、负载均衡、过滤等功能。在微服务中引入依赖org.springframework.cloud:spring-cloud-starter-zuul,使用@EnableZuulProxy注解开启Zuul网关。\[2\]\[3\] Feign是Spring Cloud中的服务调用组件,它可以简化微服务之间的调用过程。通过在微服务中引入依赖org.springframework.cloud:spring-cloud-starter-feign,可以使用Feign来定义和实现服务之间的调用接口。 综上所述,Spring Cloud提供了服务注册与发现、配置中心网关和服务调用等功能,可以帮助开发者构建和管理分布式系统中的微服务。 #### 引用[.reference_title] - *1* *3* [非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!](https://blog.csdn.net/bishe_teacher/article/details/107844103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了](https://blog.csdn.net/Cr1556648487/article/details/126543111)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值