聊聊Http服务化改造实践
在微服务架构体系中远程RPC调用主要包括Dubbo与Http调用两个大类,由于Dubbo拥有服务注册中心,并且起服务的命名非常规范,使用包名.类名.方法名进行描述。
而http调用通常都是使用httpclient等相关类库,这些在使用上并没有问题,但API都是分散在整个工程的各个地方,如果HTTP调用也可以使用类似Dubbo服务的表示方法,采用声明式定义就好了。
在开源的世界中只有想不到,没有找不到,为了解决Feign的声明式服务化管理,Feign框架应运而生,本文主要介绍如何使用Feign实现Http服务声明化管理与调用。
1.什么是Feign
Feign是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求。Feign通过注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,封装了http调用流程。
2、快速入门实例
2.1定义客户端
首先要引入Feign的maven依赖,如下图所示:
<dependency><groupId>com.netflix.feign</groupId><artifactId>feign-core</artifactId><version>8.18.0</version></dependency>
2.2 定义服务调用API(类似Dubbo API)
服务调用的API声明代码如下所示:
@FeignClient
public interface HelloControllerApi {@RequestLine("GET /api/hello?name={name}")String hello(@Param(value = "name") String name);
}
这里的要点是使用@FeignClient进行声明。声明后就可以通过HelloControllerApi进行远程HTTP调用,示例代码如下:
public class HelloControllerApiTest {private HelloControllerApi service;@Beforepublic void before(){service = Feign.builder().options(new Request.Options(1000, 3500)).retryer(new Retryer.Default(5000, 5000, 3)).target(HelloControllerApi.class, "http://127.0.0.1:8080");}@Testpublic void hello(){// 调用http://127.0.0.1:8080/api/hello?name=world 的http接口System.out.println(service.hello("world"));}}
当然需要在调用方的启动类上增加@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)注解。
2.3定义服务端
服务端与Feign并无关系,主要按照API的方式实现即可,服务端实现代码如下所示:
@Controller
@RequestMapping(value = "api")
public class HelloController {@RequestMapping(value = "/hello", method = {RequestMethod.GET})@ResponseBodypublic String list(@RequestParam String name) {return "Hello " + name;}
}//启动类
@SpringBootApplication(scanBasePackages = {"com.vhicool.manager"})
public class ManagerApplication {public static void main(String[] args) {SpringApplication.run(ManagerApplication.class, args);}
}
3.实现签名校验
上述只是简单实用Feign,接下来以实现签名校验为例展示Feign的扩展机制。
签名验证是最常见的安全机制,首先在客户端定义一个签名拦截器,用于生成签名信息,示范代码如下图所示:
public class AuthRequestInterceptor implements feign.RequestInterceptor {private TokenService tokenService;public AuthRequestInterceptor(TokenService tokenService) {this.tokenService = tokenService;}@Overridepublic void apply(RequestTemplate template) {template.header("token", tokenService.getToken());}}
并且在Feign的全局配置文件中创建对应的拦截器,示例代码如下:
public class FeignConfiguration {@Beanpublic RequestInterceptor authRequestInterceptor(ResourceIdentity resourceIdentity) {AuthRequestInterceptor authRequestInterceptor = new AuthRequestInterceptor(resourceIdentity);authRequestInterceptor.setErrorEncodeType(errorEncodeType);return authRequestInterceptor;}
}
同时在服务端获取token并对token进行校验,示例代码如下:
@Component
public class AuthFilter implements Filter {@Autowiredprivate TokenService tokeService;@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {String remoteToken = ((HttpServletRequest) servletRequest).getHeader("token");if(!tokeService.valid(token)) {//异常处理逻辑return;}filterChain.doFilter(servletRequest, servletResponse);}
}
4.服务端自动生成Feign
上面的示例虽然实现了服务接口的声明式管理,但调用端、客户端并没有显示的约束关系,接下来展示如何使用客户端、服务端使用继承方式定义服务调用API。
例如要实现如下图的效果:

原生的Feign无法实现该效果,我们需要使用OpenFeign类库,两者之间的对比如下图所示:

接下来详细介绍具体实现方法。
4.1 提取公共API
首先使用一个模块定义公共API,需要引入maven依赖,代码示例如下所示:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
接下来定义公共的服务接口,客户端、服务端都需要实现该接口,公共服务端接口定义如下:
public interface IUserController {@RequestMapping(value = "user/list-all", method = {RequestMethod.GET})List<String> listAll(@RequestParam String name);
}
4.2 服务端实现公共API
首先需要添加相应的maven依赖,代码如下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.vhicool</groupId><artifactId>feign-api</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency>
服务端采用继承方式实现,具体代码如下所示:
@Controller
@RequestMapping
public class UserController implements IUserController {@Override@ResponseBodypublic List<String> listAll(String name) {ArrayList<String> list = new ArrayList<>();list.add("达菲");list.add("olu");list.add(name);return list;}
}
4.3 客户端实现公共API
客户端首先同样需要增加相应的依赖,具体代码如下所示:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.1.5.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>compile</scope></dependency><dependency><groupId>com.vhicool</groupId><artifactId>feign-api</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency>
客户端服务调用类需要继承公共API:
@FeignClient(value = "user", url = "http://localhost:8080")
public interface UserApi extends IUserController {
}
同时客户端启动类需要增加@EnableFeignClients注解,具体示例代码如下所示:
@SpringBootApplication
@EnableFeignClients
public class ManagerApplication {public static void main(String[] args) {SpringApplication.run(ManagerApplication.class, args);}
}
同样基于Springboot编程方式,可以为Feign配置全局参数,具体如下:
@Configuration
public class FeignConfiguration {/*** 请求超时时间* @return*/@Beanpublic Request.Options options() {return new Request.Options(2000, 3500);}//拦截器等定义
}
接下来客户端就可以用如下方式进行调用:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {@Autowiredprivate UserApi userApi;@Testpublic void listAll() {System.out.println(userApi.listAll("饼饼"));}
}
当前项目编译的jar包,类也已经被替换成我们自定义的类,目标达成。
善用工具
成功的前端工程师很会善用工具,这些年低代码概念开始流行,像国外的 Mendix,国内的 JNPF,这种新型的开发方式,图形化的拖拉拽配置界面,并兼容了自定义的组件、代码扩展,确实在 B 端后台管理类网站建设中很大程度上的提升了效率。
开源地址:JNPF体验中心
代码量少,系统的稳定性和易调整性都会得到一定的保障。基于代码生成器,可一站式开发多端使用 Web、Android、IOS、微信小程序。代码自动生成后可以下载本地,进行二次开发,有效提高整体开发效率。同时,支持多种云环境部署、本地部署给予最大的安全保障,可以快速搭建适合自身应用场景的产品。
相关文章:
聊聊Http服务化改造实践
在微服务架构体系中远程RPC调用主要包括Dubbo与Http调用两个大类,由于Dubbo拥有服务注册中心,并且起服务的命名非常规范,使用包名.类名.方法名进行描述。 而http调用通常都是使用httpclient等相关类库,这些在使用上并没有问题&am…...
docker打包部署
打包成容器命令 docker build -f ./Dockerfile-long -t 名称.打包镜像 tar docker save -o 名称.tar 名称:latest执行sudo -i,提示输入用户密码,输入密码后进入超级用户(root)模式 linux上传文件 rz -ytar恢复成镜像 sudo docker…...
解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤
😀前言 在现代软件开发中,异常处理是不可或缺的一部分,它能够有效地提高系统的稳定性和健壮性。在Spring MVC框架中,异常处理机制起着至关重要的作用,它允许开发者在程序运行过程中捕获、处理和报告异常,从…...
Three.js添加阴影和简单后期处理
在Three.js中,可以使用渲染器的一些特性来实现阴影和后期处理效果。 添加阴影 要在Three.js中添加阴影效果,需要做以下几个步骤: 1.开启阴影 首先,要在渲染器中开启阴影: renderer.shadowMap.enabled true;2.设置…...
git submodule 子模块的基本使用
常用命令 命令说明git submodule add <url> <本地路径>添加子模块git submodule update --init --recursive添加子模块后,同步子模块内容git clone <url> --recurse-submodules克隆带有子模块的项目git submodule init初始化子模块git submodule…...
四层负载均衡的NAT模型与DR模型推导 | 京东物流技术团队
导读 本文首先讲述四层负载均衡技术的特点,然后通过提问的方式推导出四层负载均衡器的NAT模型和DR模型的工作原理。通过本文可以了解到四层负载均衡的技术特点、NAT模型和DR模型的工作原理、以及NAT模型和DR模型的优缺点。读者可以重点关注NAT模型到DR模型演进的原…...
【vue】vue前端实现随机验证码(数字、字母混合)功能
效果图:使用canvas组件对随机的数字字母添加插画背景、干扰线、干扰点 1、在components文件夹下新建securityCode.vue文件,代码: <template><canvas id"s-canvas" :width"contentWidth" :height"contentH…...
使用Visual Studio 2022实现透明按钮和标签、POPUP样式窗体的一种工业系统的UI例程
例程实现的功能说明 1、主窗体采用POPUP样式,无标题栏、无菜单栏,适合工业类软件 2、按钮、标签使用自绘,实现透明样式,可以实现灵活的样式设计,更具设计感 按钮重绘函数:OnDrawItem()按钮样式设定&#…...
【爬虫】7.1. JavaScript动态渲染界面爬取-Selenium
JavaScript动态渲染界面爬取-Selenium的简单学习 文章目录 JavaScript动态渲染界面爬取-Selenium的简单学习1. Selenium准备工作2. Selenium简单用法2.1. 初始化浏览器对象-webdriver.Chrome()2.2. 访问界面-browser.get()2.3. 查找节点-find_element()2.4. 节点交互-send_keys…...
菜鸟教程《Python 3 教程》笔记(12):推导式
菜鸟教程《Python 3 教程》笔记(12) 12 推导式12.1 列表推导式12.2 字典推导式12.3 集合推导式12.4 元组推导式(生成器表达式) 笔记带有个人侧重点,不追求面面俱到。 12 推导式 出处: 菜鸟教程 - Python3 …...
MAC修改python3命令为py
1, 找到python3安装路径 2, vi ~/.bash_profile 3, 增加内容: alias py“/usr/bin/python3” 4, 重载source ~/.bash_profile 5,执行py...
Windows下Git Bash调用rsync
rsync 提供了补充只需要在git安装目录下放入对应的文件即可。 需要将这个三个文件放到git的bin目录下 如果是默认安装路径是如下: C:\Program Files\Git\usr\bin 然后大功告成。...
springboot自定义事件发布及监听
自定义线程池 Configuration public class MyThreadPool {//ThreadPoolTaskExecutor不会自动创建ThreadPoolExecutor,需要手动调initialize才会创建。如果Bean就不需手动,会自动InitializingBean的afterPropertiesSet来调initializeBean("myExecut…...
手写RPC框架--2.介绍Zookeeper
RPC框架-Gitee代码(麻烦点个Starred, 支持一下吧) RPC框架-GitHub代码(麻烦点个Starred, 支持一下吧) 该项目的RPC通信将采用NettyZookeeper,所以会在前两章介绍使用方法 介绍Zookeeper Zookeepera.概述1) 数据模型2) Watcher机制 b.安装和基本操作1) Java操作zooke…...
Docker harbor 私有仓库的部署和管理
目录 一、什么是Harbor 二、Harbor的特性 三、Harbor的构成 四、部署配置Docker Harbor 1. 首先需要安装 Docker-Compose 服务 2.部署 Harbor 服务 3.使用harbor仓库 (1)项目管理 (2)用户管理 一、什么是Harbor Harbor …...
从零开始搭建AI网站(6):如何使用响应式编程
响应式编程(Reactive Programming)是一种编程范式,旨在处理异步数据流和事件流。它通过使用观察者模式和函数式编程的概念,将数据流和事件流抽象为可观察的序列,然后通过操作这些序列来实现各种功能。 在响应式编程中…...
MPI之虚拟进程拓扑
什么是虚拟进程拓扑 在很多并行应用进程中,进程的线性排列不能充分的反映进程间在逻辑上的通信模型,通常由问题几何和所用的算法决定,进程经常被排列成二维或者三维网络形式的拓扑模型而通常用一个图来描述逻辑进程排列,此种逻辑…...
Three.js相机参数及Z-Fighting问题的解决方案
本主题讨论透视相机以及如何为远距离环境设置合适的视锥体。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 透视相机是一种投影模式,旨在模仿人类在现实世界中看待事物的方式。 这是渲染 3D 场景最常用的投影模式。 - three.js 如果你看一下 Three.js 文档…...
微信小程序食疗微信小程序的设计与实现
摘要 现在人们的生活水平高了,大家都想在多活个几十年,要想实现这个想法,有很多事情都必须考虑到,第一个就是适当运动,第二个就是心情好,第三个就是要注意饮食。民以食为天,科学合理的饮食结构是…...
mac环境使用pkgbuild命令打pkg包的几个小细节
mac环境使用pkgbuild命令打pkg包的几个小细节 最近,研发提出要使用jenkins来自动生成mac环境下的pkg包,研究了一下,可以使用pkgbuild来打包。但是有几个小细节需要注意一下: 1 如果有pre-install和post-install脚本,…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
