Nacos、Nginx、Feign、Gateway开发思路
开发思路:
一、开发微服务
二、微服务之间通讯
三、微服务集群之间通讯
四、Nacos集群、Nginx(反向代理、负载均衡)
五、客户端通过网关访问微服务
一、开发微服务
服务的开发(https://www.cnblogs.com/WarBlog/p/15348825.html)
创建maven项目(父工程、子工程)
File => New => Project... =>maven
项目结构如图:
父工程依赖配置(负责管理依赖的版本springcloud、MySql、Mybatis)
注意:所有工程都需要使用springboot,所以将其配置在父工程的配置中 parent 标签
所有的子工程都需要使用的依赖,就可以通过 dependencies 标签来实现,不需要在每个子工程的pom文件中配置了

1 <parent> 2 <artifactId>spring-boot-starter-parent</artifactId> 3 <groupId>org.springframework.boot</groupId> 4 <version>2.3.9.RELEASE</version> 5 </parent> 6 <properties> 7 <java.version>1.8</java.version> 8 <spring-cloud.version>Hoxton.SR10</spring-cloud.version> 9 <mysql.version>5.1.47</mysql.version> 10 <mybatis.version>2.1.1</mybatis.version> 11 </properties> 12 <dependencyManagement> 13 <dependencies> 14 <!-- springCloud --> 15 <dependency> 16 <groupId>org.springframework.cloud</groupId> 17 <artifactId>spring-cloud-dependencies</artifactId> 18 <version>${spring-cloud.version}</version> 19 <type>pom</type> 20 <scope>import</scope> 21 </dependency> 22 <!-- mysql驱动 --> 23 <dependency> 24 <groupId>mysql</groupId> 25 <artifactId>mysql-connector-java</artifactId> 26 <version>${mysql.version}</version> 27 </dependency> 28 <!--mybatis--> 29 <dependency> 30 <groupId>org.mybatis.spring.boot</groupId> 31 <artifactId>mybatis-spring-boot-starter</artifactId> 32 <version>${mybatis.version}</version> 33 </dependency> 34 </dependencies> 35 </dependencyManagement> 36 <dependencies> 37 <dependency> 38 <groupId>org.projectlombok</groupId> 39 <artifactId>lombok</artifactId> 40 </dependency> 41 </dependencies>
子工程的依赖配置

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> </dependencies>
创建子工程中类
启动类

@SpringBootApplication public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class,args); } }
配置(配置数据库连接)、Controller、Service、Mapper、POJO
配置application.yaml(配置服务器端口、数据库连接、mybatis)

server: port: 8081 #微服务的端口 spring: datasource: url: jdbc:mysql://192.168.223.129:3306/cloud-user?useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver mybatis: type-aliases-package: com.xxx.pojo configuration: map-underscore-to-camel-case: true
POJO

import lombok.Data; @Data public class User { private Long id; private String username; private String address; }
Mapper

@Mapper public interface UserMapper { @Select("select * from tb_user where id = #{id}") User findById(@Param("id") Long id); }
Service

@Service public class UserService { @Autowired private UserMapper userMapper; public User queryById(Long id){ return userMapper.findById(id); } }
Controller

@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User queryByid(@PathVariable("id") Long id) { return userService.queryById(id); } }
启动出现异常
com.mysql.jdbc.Driver 对应 mysql-connector-java 5版本 com.mysql.cj.jdbc.Driver 对应 mysql-connector-java 6 版本
访问路径:http://localhost:8081/user/2
可以看到user的微服务已经可以访问到了,order的微服务开发和user类似
POJO

import lombok.Data; @Data public class Order { private long id; private long user_id; private String name; private long price; private int num; private User user; }
OrderService
1 @Service 2 public class OrderService { 3 @Autowired 4 private OrderMapper orderMapper; 5 6 public Order queryById(long id) 7 { 8 return orderMapper.findById(id); 9 } 10 }
访问地址:http://localhost:8082/order/101
访问成功了
下载链接:https://pan.baidu.com/s/1sQb3gjKO98bQwjKg_iXBpA提取码:ny1i
user的数据是null,微服务之间通讯如何完成???以通过RestTemplate实现
二、微服务之间通讯
@Autowired private RestTemplate restTemplate; public Order queryById(long id) { Order order = orderMapper.findById(id); String url="http://localhost:8081/user/"+order.getUserId(); User user=restTemplate.getForObject(url,User.class); order.setUser(user); return order; }
注意:mybatis默认是属性名和数据库字段名一一对应的,即 数据库表列:user_name 实体类属性:user_name
map-underscore-to-camel-case: true 使用驼峰命名 数据库表列:user_name 实体类属性:userName
访问Order微服务:http://localhost:8082/order/103
链接:https://pan.baidu.com/s/1ij1t7e0-jBgt_9aLHHM_2Q 提取码:peec
三、微服务集群之间通讯
如果Order微服务访问的User服务有多个服务怎么办??
开启多个服务
现在两个User微服务怎么能被访问到
Nacos(https://www.cnblogs.com/WarBlog/p/15398490.html)
父工程pom文件添加依赖管理

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>
子工程pom文件添加依赖

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
application.yaml配置Nacos
user微服务

spring: application: name: userservice cloud: nacos: server-addr: localhost:8848 # nacos 服务端地址
order微服务

spring: application: name: orderservice cloud: nacos: server-addr: localhost:8848 # nacos 服务端地址
启动类中的RestTemplate需要添加@LoadBalanced(@LoadBalanced 的原理:对请求地址进行替换,或者根据具体的负载策略选择服务地址,然后再去调用)
@SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class,args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
访问Nacos(http://127.0.0.1:8848/nacos/)
重启微服务
修改Order微服务的service层
@Autowired private RestTemplate restTemplate; public Order queryById(long id) { Order order = orderMapper.findById(id); String url="http://userservice/user/"+order.getUserId(); User user=restTemplate.getForObject(url,User.class); order.setUser(user); return order; }
访问Order服务(http://localhost:8082/order/101)
链接:https://pan.baidu.com/s/1tVVWTY8sGHg7Oiw-xjGGcw 提取码:3y8s
这个就可以实现微服务集群之间通讯但是RestTemplate的Url是硬编码的,可以使用Feign来完善
Feign(https://www.cnblogs.com/WarBlog/p/15419369.html)
Order微服務添加Feign依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
开启Feign
@SpringBootApplication @EnableFeignClients public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class,args); } }
编写Feign客户端

@FeignClient("userservice") public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") long id); }
将RestTemplate改为Feign的远程调用

@Autowired private UserClient userClient; public Order queryById(long id) { Order order = orderMapper.findById(id); User user = userClient.findById(order.getUserId()); order.setUser(user); return order; }
访问 http://localhost:8082/order/101
链接:https://pan.baidu.com/s/1I4Stk4__6dyY2m0XHxzUXg 提取码:ghgc
Feign优化
连接池配置
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> <version>11.5</version> </dependency>
Order微服务
feign: client: config: default: loggerLevel: Full httpclient: enabled: true # 开启feign对HttpClient的支持 max-connections: 200 # 最大的连接数 max-connections-per-route: 50 # 每个路径的最大连接数
FeignClient抽取为独立模块
添加依赖
<dependency> <groupId>com.xxx</groupId> <artifactId>feign-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
访问http://localhost:8082/order/104
链接:https://pan.baidu.com/s/1rh_4Xw3olSyUCQpA0bINiw 提取码:v9sc
上图内容已经全部实现,这样所有请求都是需要依赖Nacos来完成的,如果Nacos服务器失效的话,所有的服务就无法相应,这时就需要Nacos集群
四、Nacos集群和Nginx(https://www.cnblogs.com/WarBlog/p/15410601.html)
访问 http://localhost:8082/order/103
链接:https://pan.baidu.com/s/1_WZ1fg88I-fwSOeSYCrZMQ 提取码:qfqo
客户端可以直接访问微服务,真实微服务开发中,不可能是任何人都可以访问所有微服务,就要在访问微服务之前,添加一些过滤和认证授权的功能
五、客户端通过网关(Gateway)访问(https://www.cnblogs.com/WarBlog/p/15428522.html)
1、配置gateway的路由过滤器添加请求头信息
2、配置默认过滤器(default-filters)对所有路由请求头添加信息

spring: application: name: gateway # 服务名称 cloud: nacos: server-addr: localhost:80 # nacos地址 gateway: routes: # 网关路由配置 - id: user-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,判断请求是否符合路由规则 - Path=/user/** # 按照路径匹配,只要以/user/开头就符合要求 filters: - AddRequestHeader=info, route filter - id: order-service # 路由id,自定义,只要唯一即可 uri: lb://orderservice1 # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,判断请求是否符合路由规则 - Path=/order/** # 按照路径匹配,只要以/user/开头就符合要求 default-filters: - AddRequestHeader=info, default filter
3、通过全局过滤器(GlobalFilter)请求身份验证

@Order(-1) @Component public class AuthorizationFilter implements GlobalFilter{ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取请求参数 ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> params = request.getQueryParams(); // 2.获取参数中的 authorization 参数 String auth = params.getFirst("authorization"); // 3.判断参数值是否等于 admin if ("admin".equals(auth)) { // 4.是,放行 return chain.filter(exchange); } // 5.否,拦截 // 5.1.设置状态码 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); // 5.2.拦截请求 return exchange.getResponse().setComplete(); } }
修改OrderController和UserController读取请求头信息

@GetMapping("/{id}") public Order queryByid(@PathVariable("id") long id, @RequestHeader(value = "Info",required = false) String info) { System.out.println(info); return orderService.queryById(id); }
访问 http://localhost:10018/order/101?authorization=admin
访问 http://localhost:10018/user/1?authorization=admin
链接:https://pan.baidu.com/s/1mdvL3wlsmZtvMsmnpExbuA 提取码:zo3d
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律