聊聊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脚本,…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
