Nacos-Feign-Gateway-SpringCloud微服务
cloud_order库 tb_order表
CREATE TABLE `tb_order` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
`user_id` int(10) NOT NULL COMMENT '用户id',
`name` varchar(255) COLLATE utf8_unicode_520_ci DEFAULT '' COMMENT '物品名称',
`price` int(10) DEFAULT NULL COMMENT '价格',
`num` int(8) DEFAULT NULL COMMENT '数量',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_520_ci COMMENT='cloud_order\ntb_order表\n\n';
cloud_user 库 tb_user表
CREATE TABLE `tb_user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_520_ci DEFAULT '',
`address` varchar(255) COLLATE utf8_unicode_520_ci DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_520_ci;
maven创建项目 父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>
<groupId>com.cloud</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>user-service</module>
<module>order-service</module>
<module>gateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
<relativePath/>
</parent>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
<nacos.version>2.2.5.RELEASE</nacos.version>
<lombok.version>1.18.34</lombok.version>
</properties>
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<!--可选的-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${nacos.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
创建user-service 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cloud</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.kinroy</groupId>
<artifactId>user-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
controller
package com.kinroy.user.controller;
import com.kinroy.user.pojo.User;
import com.kinroy.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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 UserController {
@Autowired
private UserService userService;
@GetMapping("/{userId}")
public User getById(@PathVariable Long userId){
User order = userService.getById(userId);
System.out.println(order);
return order;
}
}
mapper
package com.kinroy.user.mapper;
import com.kinroy.user.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("select * from tb_user where id = #{id}")
User getById(@Param("id")Long id);
}
pojo
package com.kinroy.user.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String username;
private String address;
}
service
package com.kinroy.user.service;
import com.kinroy.user.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserService {
User getById(@Param("id")Long id);
}
impl
package com.kinroy.user.service.impl;
import com.kinroy.user.mapper.UserMapper;
import com.kinroy.user.pojo.User;
import com.kinroy.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getById(Long id) {
User user = userMapper.getById(id);
return user;
}
}
application.yml
server:
port: 8091
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
username: root
password:
driver-class-name: com.mysql.jdbc.Driver
mybatis:
type-aliases-package: com.kinroy.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
bootstrap.yml
spring:
application:
name: userservice
profiles:
active: dev
cloud:
nacos:
server-addr: localhost:8848
config:
file-extension: yaml
创建order-service 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cloud</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.kinroy</groupId>
<artifactId>order-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</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>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>com.cloud</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
controller
package com.kinroy.order.controller;
import com.kinroy.order.pojo.Order;
import com.kinroy.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
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("/order")
public class OrderController {
@Autowired
private OrderService osd;
@GetMapping("/{orderId}")
public Order getById(@PathVariable Long orderId){
Order order = osd.getById(orderId);
System.out.println(order);
return order;
}
}
mapper
package com.kinroy.order.mapper;
import com.kinroy.order.pojo.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface OrderMapper {
@Select("select * from tb_order where id = #{id}")
Order getById(@Param("id")Long id);
}
pojo
package com.kinroy.order.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private Long id;
private Integer price;
private String name;
private Integer num;
private Long userId;
private User user;
}
package com.kinroy.order.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String username;
private String address;
}
service
package com.kinroy.order.service;
import com.kinroy.order.pojo.Order;
import org.apache.ibatis.annotations.Param;
public interface OrderService {
Order getById(@Param("id")Long id);
}
impl
package com.kinroy.order.service.impl;
import com.kinroy.order.clients.UserClient;
import com.kinroy.order.mapper.OrderMapper;
import com.kinroy.order.pojo.Order;
import com.kinroy.order.pojo.User;
import com.kinroy.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper om;
@Autowired
private UserClient userClient;
@Override
public Order getById(Long id) {
Order order = om.getById(id);
User user = userClient.getUserById(order.getUserId());
order.setUser(user);
return order;
}
}
clients
package com.kinroy.order.clients;
import com.kinroy.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value="userservice")
public interface UserClient {
@GetMapping("/user/{userId}")
User getUserById(@PathVariable Long userId);
}
@FeignClient(value="userservice")
- 这个注解声明了一个名为
userservice
的 Feign 客户端。userservice
是微服务的名称,Feign 会使用服务发现机制找到对应的服务实例。
这个
UserClient
接口的作用是通过 Feign 客户端与用户服务进行通信,以便从用户服务获取特定用户的详细信息。通过这种方式,调用者可以方便地与其他微服务进行交互,而不需要直接处理 HTTP 请求和响应的细节。
-----
order-service启动项 和user-service启动项
package com.kinroy.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@MapperScan("com.kinroy.order.mapper")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
package com.kinroy.user;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@MapperScan("com.kinroy.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
@EnableFeignClients
是 Spring Cloud 提供的一个注解,主要用于启用 Feign 客户端的功能。它通常用于配置类或主应用程序类中。以下是对这个注解的详细解释:
当你在 Spring Boot 应用程序中使用
@EnableFeignClients
注解时,它会扫描指定的包(及其子包)中的接口,寻找标记了@FeignClient
注解的接口,并为这些接口自动创建代理实例。
application.yml
server:
port: 10010
spring:
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
application:
name: gateway
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cloud</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.kinroy</groupId>
<artifactId>gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>
启动
package com.kinroy.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
全局过滤器
package com.kinroy.gateway;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class GolbalFiter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> queryParams = request.getQueryParams();
String username = queryParams.getFirst("username");
if (username.equals("admin")){
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
- @Component
public class GolbalFiter implements GlobalFilter {- 使用
@Component
注解将GolbalFiter
类标记为一个 Spring 组件,使其能够被 Spring 容器管理。GolbalFiter
实现了GlobalFilter
接口,表示这是一个全局过滤器- 方法签名:
filter
方法接收两个参数:ServerWebExchange exchange
和GatewayFilterChain chain
。- 获取请求:通过
exchange.getRequest()
获取当前的 HTTP 请求。- 查询参数:通过
request.getQueryParams()
获取请求的查询参数。- 检查用户名:
- 从查询参数中获取
username
的值。- 如果
username
的值为"admin"
,则调用chain.filter(exchange)
继续执行过滤链,允许请求通过。- 否则,设置响应状态为
HttpStatus.UNAUTHORIZED
(401 未授权),并结束响应这个全局过滤器会检查每个请求的查询参数,就是个说明测试可以是token,如果
username
为"admin"
,请求会被允许继续处理;如果不是,则返回 401 未授权状态。这种机制可以用来简单地控制对某些资源的访问权限。
Nacos官网| Nacos 配置中心 | Nacos 下载| Nacos 官方社区 | Nacos 官网
sh startup.sh standalone
http://localhost:8848/nacos 本地访问
http://localhost:10010/order/1 进行测试注意增加gateway路由配置
结束