学习spring cloud项目快速搭建方法,学习nacos注册中心使用,实现两个服务间的调用

Spring Cloud 官方对自己的简短介绍:基于 Spring 构建分布式系统的工具集,简称“Spring 全家桶”。
Spring Cloud 官方对功能点的介绍:
【配置中心】Distributed/versioned configuration
【注册中心】Service registration and discovery
【API 网关】Routing
【服务调用】Service-to-service calls
【负载均衡】Load balancing
【服务容错】Circuit Breakers
【分布式消息】Distributed messaging
SpringCloudAlibaba介绍:Spring Cloud 是分布式微服务架构的一站式解决方案,它提供了一套简单易用的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务系统的构建。 Spring Cloud 提供以微服务为核心的分布式系统构建标准。

Spring Cloud 提供了非常强大的功能,但是它并不提供所有的实现,而是通过 Spring Cloud Common 子项目,定义了统一的抽象 API。而后,不同厂商结合其自身的中间件,提供自己的 Spring Cloud 套件,Spring Cloud 官方、Netflix、Alibaba 三者整理成如下表格

SpringCloud版本与SpringBoot对应关系:Spring Cloud 官方

SpringCloudAlibaba对应关系:版本发布说明 | Spring Cloud Alibaba

由于主机jdk安装的是1.8因此选用如下技术栈:
基础版本:
技术选型:
注册中心:spring-cloud-starter-alibaba-nacos-discovery
配置中心:spring-cloud-starter-alibaba-nacos-config
服务调用:spring-cloud-starter-openfeign
负载均衡:spring-cloud-loadbalancer
API网关:spring-cloud-starter-gateway

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>cloudDemoartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<modules>
<module>gateweymodule>
<module>feignconsumermodule>
<module>feignprovidemodule>
modules>
<name>cloudDemo Maven Webappname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<spring.boot.version>2.6.13spring.boot.version>
<spring.cloud.version>2021.0.5spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.5.0spring.cloud.alibaba.version>
<lombok.version>1.18.28lombok.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring.boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring.cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>${spring.cloud.alibaba.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
<optional>trueoptional>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>${spring.boot.version}version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>
性能:API高可用,负载均衡,容错机制。
安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
缓存:数据缓存。
监控:记录请求响应数据,api耗时分析,性能监控。
限流:流量控制,错峰流控,可以定义多种限流规则。
灰度:线上灰度部署,可以减小风险。
路由:动态路由规则
1、创建maven项目,修改pom.xml文件
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>cloudDemoartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>gateweyartifactId>
<packaging>warpackaging>
<name>gatewey Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bootstrapartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-loadbalancerartifactId>
dependency>
dependencies>
<build>
<finalName>gateweyfinalName>
build>
project>
2、添加启动类GatewayApplication.java
package cloud.demo.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
/**
* @ClassName GatewayApplication
* @Description TODO
* @Author c_see
* @Date 2024/2/29 11:22
* @Version 1.0
**/
@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(basePackages = {"cloud.demo"})
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
System.out.println("网关启动成功");
}
}
3、添加配置文件application.yaml
server:
port: 8081
spring:
profiles:
active: dev
application:
name: gateway-demo
cloud:
gateway:
discovery:
locator:
# 是否与服务发现组件进行结合,通过 serviceId 转发到具体的服务实例。默认为false
enabled: true
lower-case-service-id: true #使用小写service-id
nacos:
username: nacos
password: nacos
config:
server-addr: 127.0.0.1:8848
namespace: public
discovery:
server-addr: 127.0.0.1:8848
namespace: public
config:
import:
- optional:nacos:gateway-demo.yml?refreshEnabled=true
4、在nacos中添加配置gateway-demo.yml,配置动态路由
spring:
cloud:
gateway:
routes: # 网关路由配置
# 路由id,自定义,只要唯一即可
- id: feignconsumer
# 目标服务地址(uri:地址,请求转发后的地址)
# uri: http://127.0.0.1:8081 路由的目标地址http 就是固定地址,uri的协议为lb,表示启用Gateway的负载均衡功能。
# 路由的目标地址lb就是负载均衡,后面跟服务名称
uri: lb://feign-consumer
# 路由断言,也就是判断请求是否符合路由规则的条件;转发地址格式uri/archive
predicates:
# 这个是按照路径匹配,只要以 /user/ 开头就符合要求
- Path=/user/**
#fitters:
# - RewritePath=/user/?(?.*),/$\{segment}
- id: feignprovide
uri: lb://feign-provide
predicates:
- Path=/provide/**
# 在这个时间之后的请求才会被转发
#- After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>cloudDemoartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>feignprovideartifactId>
<packaging>warpackaging>
<name>feignprovide Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bootstrapartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-loadbalancerartifactId>
dependency>
dependencies>
<build>
<finalName>feignprovidefinalName>
build>
project>
package cloud.demo.provide;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @ClassName ProvideApplication
* @Description TODO
* @Author c_see
* @Date 2024/2/29 14:28
* @Version 1.0
**/
@EnableDiscoveryClient
@SpringBootApplication
public class ProvideApplication {
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class, args);
System.out.println("ProvideApplication 启动成功");
}
}
server:
port: 8082
spring:
profiles:
active: dev
application:
name: feign-provide
cloud:
nacos:
username: nacos
password: nacos
config:
server-addr: 127.0.0.1:8848
namespace: public
discovery:
server-addr: 127.0.0.1:8848
namespace: public
package cloud.demo.provide.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserProvideController {
@Value("${server.port}")
private String port;
/**
* 通过用户ID获取用户
* @param userId
* @return
*/
@GetMapping("/getUser/{userId}")
public String getUser(@PathVariable("userId") String userId){
return String.format("【%s-服务提供者】:%s", port, userId);
}
}
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>cloudDemoartifactId>
<groupId>org.examplegroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>feignconsumerartifactId>
<packaging>warpackaging>
<name>feignconsumer Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bootstrapartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-loadbalancerartifactId>
dependency>
dependencies>
<build>
<finalName>feignconsumerfinalName>
build>
project>
package cloud.demo.consumer.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 有关消费者client,配置需要调用服务者的名字
*/
@FeignClient(name = "feign-provide") //对应的要调用提供者服务名spring.application.name
public interface UserClient {
/**
* 通过用户id获取用户
* @param userId
* @return
*/
@GetMapping("/user/getUser/{userId}")//对应要调用提供者的controller
String getUser(@PathVariable("userId") String userId);
}
package cloud.demo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @ClassName ConsumerApplication
* @Description TODO
* @Author c_see
* @Date 2024/2/29 14:10
* @Version 1.0
**/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "cloud.demo.consumer.client")
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
System.out.println("ConsumerApplication 启动成功");
}
}
server:
port: 8083
spring:
profiles:
active: dev
application:
name: feign-consumer
cloud:
nacos:
username: nacos
password: nacos
config:
server-addr: 127.0.0.1:8848
file-extension: yml
discovery:
server-addr: 127.0.0.1:8848
package cloud.demo.consumer.controller;
import cloud.demo.consumer.client.UserClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 平台controller业务逻辑,引入client出发消费者调用提供者
*/
@RestController
@RequestMapping("user")
public class FeignConsumerController {
@Value("${server.port}")
private String port;
@Resource
private UserClient userClient;
/**
* 通过用户ID获取用户
* @param userId
* @return
*/
@GetMapping("/getUserInfo/{userId}")
public String getUserInfo(@PathVariable("userId") String userId){
String user = userClient.getUser(userId);
return String.format("【%s-Demo消费者】:调用Feign接口返回值 %s", port, user);
}
}
1、启动gateway、feign-provide、feign-consumer 3个模块,启动成功后在nacos可以看到服务注册成功

2、测试服务间调用

3、测试通过网关调用微服务
