首页 > 其他分享 >Feign在K8s中的使用

Feign在K8s中的使用

时间:2022-11-08 18:35:03浏览次数:46  
标签:FeignClient Feign 调用 PathVariable batteryCode Controller 使用 K8s page

Feign在K8s中的使用_spring

之前在SpringCloud中使用过@FeignClient的方式对服务进行调用,感觉使用起来还是很方便的,所以想要探索一下是否可以把@FeignClient用在K8s集群中进行服务间的调用;

feign是一个声明式web服务调用的客户端,创建一个接口并加上注解就能使用Feign了(同时支持JAX-RS类型的注解,可插入式的编码和解码),Spring Cloud Feign组件为他加入了spring mvc的注解(@RequestMappging, @RequestBody, @ResponseBody, @RequestParam, @PathVariable等)支持,以及在spring web开发过程中默认使用同样的HttpMessageConverters ,同时Spring Cloud整合了Ribbon和Eureka为使用feign的过程中提供了一个负载均衡的http客户端。

简单示例 

Feign示例(github-OpenFeign-feign):

//feign客户端声明
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);


@RequestLine("POST /repos/{owner}/{repo}/issues")
void createIssue(Issue issue, @Param("owner") String owner, @Param("repo") String repo);


}
//DTO定义
public static class Contributor {
String login;
int contributions;
}


public static class Issue {
String title;
String body;
List<String> assignees;
int milestone;
List<String> labels;
}


//启动类
public class MyApp {
public static void main(String... args) {
//注册feign客户端
GitHub github = Feign.builder()
.decoder(new GsonDecoder())
//注册feign客户端,并指定服务URL
.target(GitHub.class, "https://api.github.com");

//feign客户端进行服务调用
List<Contributor> contributors = github.contributors("OpenFeign", "feign");
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
}

SpringCloud @FeignClient示例(Declarative REST Client: Feign):

//FeignClient客户端声明(其中"stores"为SpringCloud中服务名称)
@FeignClient("stores")
public interface StoreClient {
@RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();


@RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
}


//启动类
@EnableAutoConfiguration
@EnableEurekaClient
//启动FeignClient自动配置
@EnableFeignClients
public class Application {
//自动注入FeignClient代理
@Resource
private StoreClient storeClient;

public static void main(String[] args) {
SpringApplication.run(Application.class, args);

//FeignClient进行服务调用
storeClient.update(1, new Store());
}


}


//maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>

优化

结合Maven多module的特性,可以将Controller抽象出接口定义,即在单独的一个module(如api)中,定义Controller的接口,然后在其他模块(如web) 中去实现Controller的接口,而后将api打包后上传到maven私服供公司内其他服务依赖并调用;

例如Maven项目多module结构如下:

Feign在K8s中的使用_云计算_02

api:对外提供服务的参数、返回结果DTO定义,Controller接口定义
domain:domain对象定义(entity, vo, bo, dto等)
dao:数据访问层(数据库访问、缓存访问)
service:具体服务的定义
web:controller实现层的定义

优化示例

即在api模块中进行controller接口定义:

@RequestMapping("/base")
public interface BaseController {
@RequestMapping(value = "/reqParam", method = RequestMethod.POST)
@ResponseBody
Object reqParam(@SpringQueryMap ParamVo paramVo);


@RequestMapping(value = "/reqBody", method = RequestMethod.POST)
@ResponseBody
Object reqBody(@RequestBody ParamVo paramVo);


@RequestMapping(value = "/reqPath/{batteryCode}/{page}/{rows}", method = RequestMethod.POST)
@ResponseBody
Object reqPath(@PathVariable("batteryCode") String batteryCode, @PathVariable("page") Integer page, @PathVariable("rows") Integer rows);
}

在web模块中实现controller接口:

@Controller
@RequestMapping("/base")
public class BaseControllerImpl implements BaseController {
private static final Logger logger = LogManager.getLogger(BaseControllerImpl.class);


@RequestMapping(value = "/reqParam", method = RequestMethod.POST)
@ResponseBody
public Object reqParam(@SpringQueryMap ParamVo paramVo) {
logger.info("reqParam param:{}", JsonUtils.toJson(paramVo));
return MxHttpRespUtility.successResp();
}


@RequestMapping(value = "/reqBody", method = RequestMethod.POST)
@ResponseBody
public Object reqBody(@RequestBody ParamVo paramVo) {
logger.info("reqBody param:{}", JsonUtils.toJson(paramVo));
return MxHttpRespUtility.successResp();
}


@RequestMapping(value = "/reqPath/{batteryCode}/{page}/{rows}", method = RequestMethod.POST)
@ResponseBody
public Object reqPath(@PathVariable("batteryCode") String batteryCode, @PathVariable("page") Integer page, @PathVariable("rows") Integer rows) {
logger.info("reqPath param: batteryCode={}, page={}, rows={}", batteryCode, page, rows);
return MxHttpRespUtility.successResp();
}
}

注:
@SpringQueryMap为Feign中注解,用于解析QeuryString 形式的参数,
即controller中方法参数为Object reqParam(ParamVo paramVo)形式(参数没有被@RequestParam, @RequestBody等所修饰)时,
需在controller接口定义的相应方法参数上添加@SpringQueryMap,如:Object reqParam(@SpringQueryMap ParamVo paramVo);

 

在其他服务中,依赖dev-web中api模块后,即可通过继承该controller接口的方式进行FeignClient调用:

//启动类添加注解(FeignClient自动配置)
@EnableFeignClients




//声明FeignClient,继承被调用服务的controller接口
//指定url后,即实际请求的路径即为url/requestPath(仅指定name则走SpringCloud的服务名称的负载均衡调用)
@FeignClient(name="base", url = "http://localhost:8089/dev-springboot-template")
public interface BaseControllerFeign extends BaseController {
}


//自动注入FeignClient代理
@Resource
private BaseControllerFeign baseControllerFeign;
...
//FeignClient服务调用
Object result = baseControllerFeign.reqBody(paramVo);

在k8s(或Istio)中,我们可以通过指定url=serviceName.namespace的方式来进行k8s间服务的调用,即无需通过name指定服务名称,在K8s集群中可直接通过serviceName.namespace进行服务间的调用,由K8s(或Istio)集群环境负责服务的路由与负载均衡;

示例类图如下:

Feign在K8s中的使用_云计算_03

总结

通过FeignClient的调用方式,可以将Controller抽象出接口定义,服务端来实现Controller的具体实现逻辑,而客户端依赖Controller接口定义并以此进行服务调用(由OpenFeign客户端对Controller中SpringMVC的注解进行解析并转换为相应的Http调用),此种方式中Controller接口定义为客户端和服务端二者之间连接的桥梁,通过Maven多module的形式使得Controller接口定义得以在多个应用间进行传递复用,而在K8s(Istio)中可以通过指定url=serviceName.namespace/contextPath来进行服务间的请求调用,由K8s(或Istio)集群环境负责服务的路由与负载均衡;

问题:FeignClient接口定义并不是完全符合SpringMVC规范,可能会对原Controller接口进行调整方能完全适配;例如@SpringQueryMap注解的使用,以及@PathVariable需要对应到每个参数上,例如原Controller实现定义如下:

@RequestMapping(value = "/reqPath/{batteryCode}/{page}/{rows}", method = RequestMethod.POST)
@ResponseBody
public Object reqPath(ParamVo paramVo) {
logger.info("reqPath param:{}", JsonUtils.toJson(paramVo));
return MxHttpRespUtility.successResp();
}

但是FeignClient需要修改如下形式才可正确调用:

@RequestMapping(value = "/reqPath/{batteryCode}/{page}/{rows}", method = RequestMethod.POST)
@ResponseBody
Object reqPath(@PathVariable("batteryCode") String batteryCode, @PathVariable("page") Integer page, @PathVariable("rows") Integer rows);

以上只是简单的了解,若想真正像使用Feign进行K8s间服务调用,还需对spring-cloud-starter-openfeign源码进行分析与重构,删除不必要的依赖...


------------------- 消息中间件Rabbitmq ----------------------------------

消息中间件Rabbitmq(01)

消息中间件Rabbitmq(02)

消息中间件Rabbitmq(03)

消息中间件Rabbitmq(04)

消息中间件Rabbitmq(05)

消息中间件Rabbitmq(06)

消息中间件Rabbitmq(07)

------------------- ---------- 云计算  -------------------------------------

云计算(1)——docker的前世今生

云计算(2)—— 体系结构

云计算(3)—— 容器应用

云计算(4)—— LAMP

云计算(5)—— Dockerfile云计算(6)—— harbor

云计算(7)—— 网络

云计算(8)—— jekins(1)

云计算(9)—— jekins(2)



关注公众号 soft张三丰 

Feign在K8s中的使用_spring_04

标签:FeignClient,Feign,调用,PathVariable,batteryCode,Controller,使用,K8s,page
From: https://blog.51cto.com/u_15501087/5834173

相关文章

  • k8s服务发现和负载均衡
    概述:KubernetesService定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略——通常称为微服务。这一组Pod能够被Service访问到,通常是通过LabelSelecto......
  • mysql 5.7安装及使用binlog日志恢复数据库
    目录mysql5.7安装及使用binlog日志恢复数据库binlog日志介绍安装mysql5.7开启Binlog日志查看binlog日志状态和内容通过Binlog恢复数据清理MySQL的binlog日志自动删除手动......
  • ubuntu加入k8s
    一、安装docker所需的工具(安装最新版即可)apt-getupdateapt-getinstalldocker.io-y设置开机启动并启动dockersudosystemctlstartdockersudos......
  • 配置sshd_使用CA签名证书登录_更新sshd服务端的通讯密钥
    配置sshd_使用CA签名证书登录_更新sshd服务端的通讯密钥转载注明来源:本文链接来自osnosn的博客,写于2022-11-06.用CA签名证书登录请参考【SSH证书登录教程】,这个......
  • JavaScript 中如何使用状态模式简化对象
    英文|https://medium.com/frontend-canteen/simplify-your-object-with-state-pattern-in-javascript-8674ff46edb1翻译|杨小爱状态模式是一个有趣的模式,它可能是解决一......
  • 9 个你可能从未使用过的很棒的 CSS 属性
    英文|https://javascript.plainenglish.io/9-awesome-css-properties-that-you-probably-have-never-used-8cc4c385c3c6翻译| 杨小爱如今,网络上的每个网站或Web应用程......
  • DGL使用手记
    DGL简介DGL(DeepGraphLibrary)是一个用于搭建图神经网络的框架,支持pytorch,TensorFlow,MXNet等机器学习框架,集成了图神经网络的许多功能.编写这篇文章的契机是由于t......
  • rancher控制k8s
    前言:rancher主要可以管理和创建k8s集群并在rancher上面做操作,类似于k8s自带的控制面板能够监控集群但是功能有比面板多,详细专业的解释请看官网。......
  • MvvmLight的接班人CommunityToolkit.Mvvm包使用介绍
    前面在一家军工类企业上班,公司没有网。最近在需要使用MVVM框架的时候才发现MvvmLight作者宣布停止更新了,有点可惜。微软出了一个CommunityToolkit.Mvvm包来接MvvmLight的......
  • 完整的Android使用Messenger实现跨app通信,设置api和sdk版本30以上,设置包可见性(Androi
    服务端packagecom.jay.msgapp2;importandroid.app.Service;importandroid.content.Intent;importandroid.os.Bundle;importandroid.os.Handler;importandroi......