springboot和flask整合nacos,使用openfeign实现服务调用,使用gateway实现网关的搭建(附带jwt续约的实现)

环境准备:

插件版本
jdk21
springboot

3.0.11

springcloud

2022.0.4

springcloudalibaba

2022.0.0.0

nacos2.2.3(稳定版)
python3.8

nacos部署(docker)

先创建目录,分别创建config,logs,data目录,单独创建一个容器

docker run -d \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-p 7848:7848 \
-v /data/nacos/conf:/mnt/data3/dockerfiles/nacos/config \
-v /data/nacos/logs:/mnt/data3/dockerfiles/nacos/logs \
-v /data/nacos/data:/mnt/data3/dockerfiles/nacos/data \
--name nacos-mysql \
--restart=always \
nacos/nacos-server:v2.2.3

 将配置文件拷贝出来(主要是application.properties和logback.xml)

docker cp nacos-mysql:/home/nacos/conf ./

修改mysql的信息(修改文件application.properties)

再次运行

docker run -d \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-p 7848:7848 \
-v /data/nacos/conf:/mnt/data3/dockerfiles/nacos/config \
-v /data/nacos/logs:/mnt/data3/dockerfiles/nacos/logs \
-v /data/nacos/data:/mnt/data3/dockerfiles/nacos/data \
--name nacos-mysql \
--restart=always \
nacos/nacos-server:v2.2.3

开启服务器端口:

centos开启防火墙端口 

 访问 ip:port/nacos

出现此页面即为安装成功。

springboot注册到nacos

先贴一个pom.xml

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.11</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>platform</artifactId><version>0.0.1-SNAPSHOT</version><name>platform</name><description>platform</description><properties><java.version>21</java.version><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.2</version></dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!--        </dependency>--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.2</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.2</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>edge-SNAPSHOT</version></dependency><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.41</version></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency></dependencies><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>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>projectlombok.org</id><url>https://projectlombok.org/edge-releases</url></repository></repositories><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件bootstrap.yml

spring:application:name: platformcloud:nacos:server-addr: ip:portconfig:file-extension: ymlgroup: DEFAULT_GROUPprefix: ${sping.application.name}

springboot启动类

@SpringBootApplication
@EnableFeignClients
@EnableCaching
@EnableScheduling
@EnableDiscoveryClient
@RefreshScope
public class PlatformApplication {public static void main(String[] args) {SpringApplication.run(PlatformApplication.class, args);}}

启动后就可以将服务注册到nacos中

python集成flask注册到nacos

首先下载nacos的sdk包

pip install nacos-sdk-python

python代码

import glob
import nacos
import threading
from flask import request, send_file
from flask import Flask, Response# nacos注册中心配置
SERVER_ADDRESS = "http://ip:port"
client = nacos.NacosClient(SERVER_ADDRESS)def service_register():"""ephemeral参数:是否是临时服务,应为false; 刚才上面也提到了,如果是 非临时实例,客户端就无需主动完成心跳检测。因此此处将服务注册为 非临时实例"""client.add_naming_instance("train", "ip", "port", ephemeral=False)# 测试nacos
@app.route("/testNacos/<testId>", methods=["GET"])
def testNacos(testId):resMap = {}print("nacos: {}".format(testId))resMap["code"] = "200"resMap["message"] = "hello nacos"resMap["data"] = str(testId)response = Response(json.dumps(resMap), status=200,content_type='application/json')return responseif __name__ == "__main__":# main()threading.Timer(5, service_register).start()app.run("0.0.0.0", 12352)

启动后就可以将服务注册到nacos中

到这里,服务注册到nacos已经完成了

使用openfeign进行服务间的调用

@FeignClient("train")
public interface InferRpcService {@GetMapping("/testNacos/{testId}")VitsResponse testNacos(@PathVariable String testId);
}

测试类

@Test
public void testNacosPy(){System.out.println(trainService.testNacos("232323"));
}

执行后

 

经测试没有问题

gateway网关服务

pom.xml

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.11</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>gateway</artifactId><version>0.0.1-SNAPSHOT</version><name>gateway</name><description>gateway</description><properties><java.version>21</java.version><spring-cloud.version>2022.0.4</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.41</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency></dependencies><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>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件(bootstrap.yml)

spring:application:name: gatewaycloud:nacos:server-addr: ip:portconfig:file-extension: ymlgroup: DEFAULT_GROUPprefix: ${sping.application.name}gateway:# 下游服务https配置httpclient:ssl:use-insecure-trust-manager: trueroutes:- id: platformuri: lb://platformpredicates:- Path=/api/platform/**filters:- StripPrefix=2

启动类

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

jwt续约

工具类

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;import java.time.LocalDateTime;
import java.util.*;@Slf4j
public class JWTUtils {private static final String SING = "auth";public static String getToken(Map<String, String> map) {Calendar instance = Calendar.getInstance();instance.add(Calendar.MINUTE, 30);JWTCreator.Builder builder = JWT.create();map.forEach((k, v) -> {builder.withClaim(k, v);});String token = builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(SING));return token;}public static DecodedJWT verify(String token) {return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);}/*** 查看是否需要续约** @param jwtToken 前端的* @return -1过期,不需要续约  0 不需要操作  1 需要续约*/public static int renewed(String jwtToken) {DecodedJWT verify = null;try {verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(jwtToken);if (Objects.nonNull(verify)) {log.info("过期时间: {}", verify.getExpiresAt());Date date = verify.getExpiresAt();if (date.before(new Date())) {log.info("token已过期");return -1;} else if (DateUtils.toLocalDateTime(date).minusMinutes(15L).isAfter(LocalDateTime.now())) {log.info("token处于正常状态");return 0;} else if (DateUtils.toLocalDateTime(date).minusMinutes(15L).isBefore(LocalDateTime.now())) {log.info("token需要续签");return 1;}}} catch (JWTVerificationException | IllegalArgumentException e) {log.info("token已过期");return -1;}log.info("token已过期");return -1;}public static String doRenewed(String number) {Map<String, String> map = Collections.singletonMap("openid", number);return getToken(map);}
}
public class DateUtils {public static LocalDateTime toLocalDateTime(Date date){return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();}
}

全局过滤器

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.gateway.constant.Constant;
import com.example.gateway.constant.LoginConstant;
import com.example.gateway.constant.VitsCloneConstant;
import com.example.gateway.dto.response.CommonResponse;
import com.example.gateway.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 获取请求路径String path = request.getPath().toString();log.info("path:{}", path);// 当前过滤器只处理语音克隆相关的请求if (StringUtils.contains(path, VitsCloneConstant.API_PREFIX)) {// 如果是登录接口,直接放行if (StringUtils.contains(path, LoginConstant.LOGIN_PATH)) {return chain.filter(exchange);}// 获取请求头中的Authorization字段String token = request.getHeaders().getFirst(LoginConstant.AUTHORIZATION_HEADER);// 如果校验失败,返回未授权状态if (StringUtils.isEmpty(token)) {CommonResponse<String> error = CommonResponse.error("无效的授权信息", "无效的授权信息");response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.writeWith(Mono.just(response.bufferFactory().wrap(JSON.toJSONBytes(error))));}int renewed = JWTUtils.renewed(token);if (renewed == -1) {log.info("token已过期");CommonResponse<String> error = CommonResponse.error("无效的授权信息", "无效的授权信息");response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.writeWith(Mono.just(response.bufferFactory().wrap(JSON.toJSONBytes(error))));} else if (renewed == 0) {log.info("jwtToken状态正常,无需操作");DecodedJWT verify = JWTUtils.verify(token);String openid = verify.getClaims().get("openid").asString();ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().header("openId", openid).build();return chain.filter(exchange.mutate().request(modifiedRequest).build());} else {DecodedJWT verify = JWTUtils.verify(token);String openid = verify.getClaims().get("openid").asString();log.info("当前需要续约的jwtToken的用户手机号码: {}", openid);token = JWTUtils.doRenewed(openid);response.getHeaders().set(LoginConstant.AUTHORIZATION_HEADER, token);ServerHttpRequest modifiedRequest = exchange.getRequest().mutate().header("openId", openid).build();return chain.filter(exchange.mutate().request(modifiedRequest).build());}}return chain.filter(exchange);}@Overridepublic int getOrder() {return -900;}}

常量类

public interface Constant {String TOKEN = "token";
}
public interface LoginConstant {String LOGIN_PATH = "/login";String AUTHORIZATION_HEADER = "token";
}
public interface VitsCloneConstant {String API_PREFIX="/api/platform/";
}

启动网关后,就可以通过网关访问服务了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/175810.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

APISpace 全国快递物流地图轨迹查询API接口案例代码

1.全国快递物流地图轨迹查询接口详解 1.1 接口请求 请求方式&#xff1a;POST请求地址&#xff1a;https://eolink.o.apispace.com/wldtgj1/paidtobuy_api/trace_map请求头&#xff1a; 标签必填说明X-APISpace-Token是鉴权私钥&#xff0c;登陆 APISpace 后在管理后台的[访…

证照之星XE专业版下载专业证件照制作工具

值得肯定的是智能背景替换功能&#xff0c;轻松解决背景处理这一世界难题。不得不提及的是新增打印字体设置&#xff0c;包含字体选择、字号大小、字体颜色等。不同领域的应用证明了万能制作&#xff0c;系统支持自定义证照规格&#xff0c;并预设了17种常用的证件照规格。人所…

紧急:发现NGINX Ingress Controller for Kubernetes中的新安全漏洞

导语 大家好&#xff0c;今天我要向大家紧急报告一则消息&#xff1a;我们在NGINX Ingress Controller for Kubernetes中发现了三个新的安全漏洞&#xff01;这些漏洞可能被黑客利用&#xff0c;从集群中窃取机密凭据。在本文中&#xff0c;我们将详细介绍这些漏洞的细节&#…

ROCKCHIP ~ Camera 闪光灯

一、闪光灯基本原理 工作模式 Camera flash led分flash和torch两种模式。 flash&#xff1a; 拍照时上光灯瞬间亮一下&#xff0c;电流比较大&#xff0c;目前是1000mA&#xff0c;最大电流不能超过led最大承受能力 torch&#xff1a; 只用于录video或者拿led当手电筒的情况&…

python多环境并存

1. 现况简介 1.1 本人windows所存Python版本 Python 2.7 Python 3.6 Python 3.7 1.2 Python 各版本路径如下 Python 2.7Python 3.6Python 3.7C:\Server\Python27C:\Server\Python36C:\Server\Python37 1.3 系统环境变量配置如下 2. 解决方案 2.1 进入目录 cd C:\Server…

qt5工程打包成可执行exe程序

一、编译生成.exe 1.1、在release模式下编译生成.exe 1.2、建一个空白文件夹package&#xff0c;再将在release模式下生成的.exe文件复制到新建的文件夹中package。 1.3、打开QT5的命令行 1.4、用命令行进入新建文件夹package&#xff0c;使用windeployqt对生成的exe文件进行动…

84.在排序数组中查找元素的第一个和最后一个位置(力扣)

目录 问题描述 代码解决以及思想 知识点 问题描述 代码解决以及思想 class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {int left 0; // 定义左边界int right nums.size() - 1; // 定义右…

2023年10月13日,美国材料与试验协会(ASTM)发布了新版玩具安全标准ASTM F963-23

新标准发布 2023年10月13日&#xff0c;美国材料与试验协会&#xff08;ASTM&#xff09;发布了新版玩具安全标准ASTM F963-23。 主要更新内容 与ASTM F963-17相比&#xff0c;此次更新包括&#xff1a;单独描述了基材重金属元素的豁免情况&#xff0c;更新了邻苯二甲酸酯的管…

【ROS入门】雷达、摄像头及kinect信息仿真以及显示

文章结构 雷达信息仿真以及显示Gazebo仿真雷达配置雷达传感器信息xacro文件集成启动仿真环境 Rviz显示雷达数据 摄像头信息仿真以及显示Gazebo仿真摄像头新建xacro文件&#xff0c;配置摄像头传感器信息xacro文件集成启动仿真环境 Rviz显示摄像头数据 kinect信息仿真以及显示Ga…

基于深度学习网络的美食检测系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 % 图像大小 image_size [224 224 3]; num_classes size(VD,2)-1;% 目标类别数量…

可视化 | 数据可视化降维算法梳理

文章目录 &#x1f4da;数据描述&#x1f407;iris&#x1f407;MNIST &#x1f4da;PCA&#x1f407;算法流程&#x1f407;图像描述 &#x1f4da;Kernel-PCA&#x1f407;算法流程&#x1f407;图像描述 &#x1f4da;MDS&#x1f407;算法流程&#x1f407;图像描述 &#…

Linux两条服务器实现相互免密登录

1.准备两台虚拟机&#xff0c;一台充当服务器端&#xff08;server&#xff09;&#xff0c;一台充当客户端&#xff08;client&#xff09; 服务器端&#xff08;server&#xff09;&#xff1a;192.168.75.139 客户端&#xff08;client&#xff09;&#xff1a;192.168.75…

Fegin ----微服务 SpringCloud

FeignClient 是一个注解&#xff0c;用于创建一个声明式的 REST 客户端&#xff0c;用于访问其他服务的 REST API。通过 Feign Client&#xff0c;可以将远程服务的 API 当做本地服务进行调用&#xff0c;Feign Client 能够自动生成 API 客户端的实现类&#xff0c;在使用 API …

node使用fs模块(一)—— 写入文件的基本使用

文章目录 前言一、写入文件的使用&#xff08;fs.writeFile&#xff09;1.参数说明2.基本使用(1)新建app.js 文件(2)代码如下(3)执行命令(4&#xff09;效果 3.写入文件的同步和异步&#xff08;1&#xff09;默认异步&#xff08;2&#xff09; 同步方法&#xff08;writeFile…

jmeter界面压测过程卡死解决思路

1、排查压测机的资源是否充足&#xff1b; 2、检查jmeter压测脚本&#xff0c;除聚合报告的所有组件关闭&#xff1b; 我在压测过程中出现频繁卡死&#xff0c;就是查看结果数和断言结果信息量过多导致&#xff1a; 3、直接用非gui界面形式&#xff0c;也就是脚本形式压测。

3D虚拟样板间场景制作软件的应用优势及价值

高端家装样板间不仅代表着高品质的家居生活&#xff0c;还是一种生活态度和品味的体现。为了让客户能够更好地体验到高端家装样板间的魅力&#xff0c;许多家装公司和房地产开发商开始尝试使用VR技术来进行样板间的拍摄和展示。通过VR全景拍摄&#xff0c;客户可以在线上进行参…

css小程序踩坑记录

写标签设置距离 一直设置不动 写个双层 设置动了 神奇 好玩

qt-gui

C常用GUI开发框架Qt&#xff0c;开始支持Python 2018-12-24 12:49 C的GUI接口开发框架Qt宣布&#xff0c;在5.12版本中开始支持Python&#xff0c;Python开发人员现在可以使用所有的Qt API&#xff0c;目前仍在技术预览版的阶段&#xff0c;但官方也承诺&#xff0c;正式版将…

蓝桥杯每日一题2023.10.30

题目描述 日志统计 - 蓝桥云课 (lanqiao.cn) 题目分析 本题可以使用双指针来维护时间段的区间&#xff0c;在维护的时间段内确定是否为热帖 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N 2e5 10; struct node {int t, id; }tiee…

OBS直播软件使用NDI协议输入输出

OBS&#xff08;Open Broadcaster Software&#xff09;是一个免费的开源的视频录制和视频推流软件。其功能强大并广泛使用在视频导播、录制及直播等领域。 OBS可以导入多种素材&#xff0c;除了本地音频、视频、图像外&#xff0c;还支持硬件采集设备&#xff0c;更能支持各种…