3.2.4 Feign开发

 

 

1 本文目标

通过本章节,将掌握Feign接口的开发及使用,Feign常用的安全机制。

1.1 Feign简单介绍

微服务之前的通信、服务调用,可以通过Feign来实现,而其通讯的本质就是发送HTTP请求。

 

2 练习场景

本次练习需要创建三个模块:

  • 客户管理微服务模块(custmng):服务提供方提供客户额度管理查询功能;
  • 信誉度管理微服务模块(creditmng):服务消费方,消费额度管理功能的查询功能;
  • 客户管理Client模块(custmng-client):客户管理提供给其他微服务模块使用的接口模块;

 

前提:

  • 本章节使用的微服务模块custmng(复用3.2.3章节创建的微服务工程);
  • 为提供方微服务custmng的额度表准备测试数据,用于消费方查询使用; 

    insert into limit_info (LIMIT_ID, LIMIT_CODE, LIMIT_AMT, LIMIT_DESC, LIMIT_USER_ID)
    values ('00000', '101010', '2222222', 'airabl', 'air');

  • 为custmng微服务的LimitInfoResource.java新增方法query

    @RestController

    @RequestMapping("/api/limitinfo")

    public class LimitInfoResource extends CommonResource<LimitInfo, String>{

        @Autowired

        private LimitInfoService limitInfoService;

     

        @Override

        protected CommonService getCommonService() {

            // TODO 自动生成的方法存根

            return limitInfoService;

        }

     

        @GetMapping(value="/query")

        public LimitInfo query(@RequestParam(value="limitId") String limitId) {

            return limitInfoService.selectByPrimaryKey(limitId);

        }

    }

3 操作步骤

为custmng微服务创建SDK模块

3.1 服务提供方custmng微服务

 

3.1.1 custmng-client模块创建

通常,某个微服务需要提供接口给其他微服务模块时,需要开发并封装Client模块,

其他微服务通过pom引入的方式,进行接口消费,且必须在统一注册中心集群环境下;

 

基于已经创建微服务工程->右键“模块”->选择Client

 

创建后工程结构

 

3.1.2 接口创建

在custmng-client工程下,应用开发->业务开发->业务逻辑->右键,新建类

DTO创建

package cn.com.yusys.yusp.service;

import java.io.Serializable;

/**

 * 额度实体表.

 *

 * @since 2.1.1

 */

public class LimitInfoDTO  implements Serializable{

    private static final long serialVersionUID = 1L;

    /**

     * 额度ID

     */

    private String limitId;

     

    /**

     * 额度代码

     */

    private String limitCode;

     

    /**

     * 额度金额

     */

    private String limitAmt;

     

    /**

     * 描述

     */

    private String limitDesc;

     

    /**

     * 客户ID

     */

    private String limitUserId;

     

     

    /**

     * @param limitId

     */

    public void setLimitId(String limitId) {

        this.limitId = limitId == null ? null : limitId.trim();

    }

     

    /**

     * @return LimitId

     */

    public String getLimitId() {

        return this.limitId;

    }

     

    /**

     * @param limitCode

     */

    public void setLimitCode(String limitCode) {

        this.limitCode = limitCode == null ? null : limitCode.trim();

    }

     

    /**

     * @return LimitCode

     */

    public String getLimitCode() {

        return this.limitCode;

    }

     

    /**

     * @param limitAmt

     */

    public void setLimitAmt(String limitAmt) {

        this.limitAmt = limitAmt == null ? null : limitAmt.trim();

    }

     

    /**

     * @return LimitAmt

     */

    public String getLimitAmt() {

        return this.limitAmt;

    }

     

    /**

     * @param limitDesc

     */

    public void setLimitDesc(String limitDesc) {

        this.limitDesc = limitDesc == null ? null : limitDesc.trim();

    }

     

    /**

     * @return LimitDesc

     */

    public String getLimitDesc() {

        return this.limitDesc;

    }

     

    /**

     * @param limitUserId

     */

    public void setLimitUserId(String limitUserId) {

        this.limitUserId = limitUserId == null ? null : limitUserId.trim();

    }

     

    /**

     * @return LimitUserId

     */

    public String getLimitUserId() {

        return this.limitUserId;

    }

}

 

3.1.3 创建Feign接口服务

package cn.com.yusys.yusp.service;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestParam;

/**

 * 额度管理API接口.

 *

 * @since 2.1.1

 */

@FeignClient(name = "custmng", path = "/api", fallback = LimitInfoServiceHystrix.class)

public interface LimitInfoService {

    /**

     * 额度信息查询接口.

     *

     * @param limitId

     *            额度ID

     * @return

     */

    @GetMapping(value = "/limitinfo/query")

    public LimitInfoDTO query(@RequestParam(value = "limitId") String limitId);

}

@FeignClient 标注此接口为Feign接口,需要通过@EnableFeignClients扫描后才会生效 

name = custmng #微服务名称

value = /api/limitinfo/query #提供对外资源服务的API

method = RequestMethod.GET #HTTP方法类型

@RequestParam("limitId") String limitId#基于GET请求的参数传值

 

3.1.4 fallback开发

        在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可。

要为给定的@FeignClient启用回退,请将fallback属性设置为实现Hystrix的类名.@FeignClient(fallback = LimitInfoServiceHystrix.class)

package cn.com.yusys.yusp.service;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

/**

 * 额度管理熔断处理实现类.

 *

 * @since 2.1.1

 */

@Component

public class LimitInfoServiceHystrix implements LimitInfoService {

    private static final Logger logger = LoggerFactory.getLogger(LimitInfoServiceHystrix.class);

    @Override

    public LimitInfoDTO query(String limitId) {

        logger.warn("访问失败,触发熔断");

        return null;

    }

}

注意,此处只能使用@Component 注解

3.1.5 接口发布

完成接口自测后,即可将client包按照版本规范,发布到maven仓库,同时通过wiki或文档等方式,提供API、参数的说明文档。

在工程目录执行

mvn deploy -e -DskipTests

 

发布前提

  • 本机已安装apache maven
  • setting 配置maven私服账号信息

  • 工程pom增加发布的具体仓库信息

3.2 消费者消费

3.2.1 创建creditmng微服务模块

该微服务工程开发为消费端,调用custmng提供第SDK接口;创建流程和custmng创建流程一直,此处不再重复讲解;

除了调整数据库、Redis配置,此微服务使用6002端口;

3.2.2 为/creditmng/pom.xml增加SDK包依赖

<dependency>

    <groupId>cn.com.yusys.yusp</groupId>

    <artifactId>custmng-client</artifactId>

    <version>2.1.1-SNAPSHOT</version>

</dependency>

 

3.2.3 增加@EnableFeignClients配置

CreditmngMicroserviceApp.java 增加@EnableFeignClients配置

消费方在消费服务提供发布的client包时,需要通过注解EnableFeignClients的方式开启Feign功能,同时,在注解中添加Feign接口需要扫描的包路径,

在应用入口的启动类上,添加了EnableFeignClients,如:@EnableFeignClients("cn.com.yusys.yusp")

@EnableConfigurationProperties({ApplicationProperties.class})

@EnableDiscoveryClient

@SpringBootApplication(scanBasePackages = {"cn.com.yusys.yusp"},

    exclude = {JmxAutoConfiguration.class, ThymeleafAutoConfiguration.class,

            SecurityAutoConfiguration.class, JasyptSpringBootAutoConfiguration.class})

@MapperScan({"cn.com.yusys.yusp.repository.mapper"})

@EnableFeignClients("cn.com.yusys.yusp")

@EnableTransactionManagement

public class CreditmngMicroserviceApp {

    private static final Logger logger = LoggerFactory.getLogger(CreditmngMicroserviceApp.class);

    public static void main(String[] args) {

        Environment env = SpringApplication.run(CreditmngMicroserviceApp.class, args).getEnvironment();

        logger.info(AppStartMessageUtil.updServiceStartMessage(env));

    }

}

或者是增加FeignConfiguration配置类,用于开启Feign配置,并为它设置相关的属性;

 

3.2.4 增加接口消费

在使用feign时,和常用bean注入方式一样,通过@Autowired注解,即可实现bean注入:

@RestController

@RequestMapping("/api/consumer")

public class ConsumberResource {

    @Autowired

    LimitInfoService  limitInfoService;

     

    @GetMapping(value="/query")

    public String query(@RequestParam(value="limitId") String limitId) {

        LimitInfoDTO limitInfoDTO = limitInfoService.query(limitId);

        return Optional.ofNullable(limitInfoDTO)

                .map(LimitInfoDTO::getLimitDesc)

                .orElseGet(()->"");

    }

}

 

3.3 测试

通过swagger进行测试,如果没有开启swagger,可以通过application.swagger.enabled=true开启

custmng、creditmng应用启动,可通过http://localhost:6002/actuator/beans 查看FeignBean注入信息

"cn.com.yusys.yusp.service.LimitInfoService" : {

   "aliases" : [ "custmngFeignClient" ],

   "scope" : "singleton",

   "type" : "cn.com.yusys.yusp.service.LimitInfoService",

   "resource" : null,

   "dependencies" : [ ]

 },

从以上内容可以了解到,每一个接口都会有一个别名:微服务+FeignClient,标识由bean是有feign创建。

3.3.1 调用custmng接口,查看服务提供方接口查询

http://172.16.20.208:6001/api/limitinfo/query?limitId=00000

3.3.2 调用creditmng接口,查询消费方接口消费

 http://localhost:6002/api/consumer/query?limitId=00000

点击try it out,swagger测试结果:

3.3.3 shutdown custmng微服务,重新查询

因为微服务默认开启了熔断

#Feign启动okhttp3

feign:

    httpclient:

        enabled: false

    okhttp:

        enabled: true

    hystrix:

        enabled: true

所以,Feign失败后,会触发熔断逻辑:

[creditmng, 172.16.20.208] WARN  2019-03-14 20:23:12.875 [hystrix-custmng-1, f25a6fb186591006, 8f3e7289a868ad86] cn.com.yusys.yusp.service.impl.LimitInfoServiceHystrix.query:22 - 访问失败,触发熔断

响应内容为熔断缺省内容:空字符串,Swagger测试结果:

4 进阶

nameurl属性支持占位符,如

@FeignClient(name = "${feign.name}", url = "${feign.url}")

public interface UserProviderService {

    //..

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值