Feign是一个声明式的Web服务客户端,可帮助我们更加便捷、优雅地调用HTTP API

Feign可以与Eureka和Ribbon组合使用以支持负载均衡

一、构建Eureka Server

【基于第二章节创建的Eureka Server】

二、构建Eureka Client提供者集群项目

【基于第三章节构建的Eureka Client提供者集群项目】

1:提供者集群项目中创建controller

mhb-cloud-producer mhb-cloud-producer-extend

【创建UserVo对象】com\applesnt\vo\UserVo.java

package com.applesnt.vo;
import lombok.Data; @Data
public class UserVo { private String user_id; private String user_name; private String code; public UserVo(String user_id, String user_name, String code) {
this.user_id = user_id;
this.user_name = user_name;
this.code = code;
} public UserVo() {
}
}

mhb-cloud-producer :9904

mhb-cloud-producer-extend:9905

【创建Controller】com\applesnt\controller\FeignProducerController.java

package com.applesnt.controller;

import com.applesnt.vo.UserVo;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; @RestController
@RequestMapping("/producer")
public class FeignProducerController { /*返回传递过来的id
* 请求路径:http://localhost:9904/producer/get/123
* */
@GetMapping("/get/{id}")
public String getId(@PathVariable("id") String id){
System.out.println("-----"+id);
return "我是提供者 端口是9904 传递的参数= "+id;
} /*参数为id 返回user对象
* 请求路径:http://localhost:9904/producer/getuserbyid/123
* */
@GetMapping("/getuserbyid/{id}")
public UserVo getUserById(@PathVariable("id") String id){
UserVo userVo = new UserVo();
userVo.setUser_id(id);
userVo.setUser_name("applesnt");
userVo.setCode("9904");
return userVo;
} /*
* 返回user对象
* 访问路径:http://localhost:9904/producer/getuser2?id=123&name=lisi
* */
@GetMapping("/getuser2")
public UserVo getUser2(@RequestParam("id") String id,
@RequestParam("name") String name){
UserVo userVo = new UserVo();
userVo.setUser_id(id);
userVo.setUser_name(name);
userVo.setCode("9904");
return userVo;
} /*
* 返回user对象
* 访问路径:http://localhost:9904/producer/getuser3?user_id=123&user_name=lisi
* */
@GetMapping("/getuser3")
public UserVo getUser3(UserVo userVo){
userVo.setUser_id(userVo.getUser_id());
userVo.setUser_name(userVo.getUser_name());
userVo.setCode("9904");
return userVo;
} /*参数uservo 返回UserVo
* postman body--raw(选择json格式)
* 数据格式:{"user_id":"123","user_name":"zhangsan"}
* */
@PostMapping("/getuser")
public UserVo getUser(@RequestBody UserVo userVo){
return userVo;
} /*返回UserVo集合
* 请求路径:http://localhost:9904/producer/getlist/
* */
@GetMapping("/getlist")
public List<UserVo> getUserList(){ List<UserVo> voList = new ArrayList<>();
UserVo userVo1 = new UserVo("1","zhangsan","9904");
UserVo userVo2 = new UserVo("2","lisi","9904");
UserVo userVo3 = new UserVo("3","wangwu","9904");
voList.add(userVo1);voList.add(userVo2);voList.add(userVo3); return voList;
}
}

三、创建Eureka消费者项目(基于Feign)

mhb-cloud-consumer-Feign:【端口 8801】

1:pom文件

<!--eureka客户端环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <!--feign环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2:application.yml文件

debug: false

spring:
application:
name: mhb-cloud-consumer-feign #每一个微服务必须有这个应用名称 server:
port: 8801 #端口 eureka:
instance:
appname: consumer-feign #eureka application的名称
prefer-ip-address: true #开启ip显示eureka的主机服务
#eureka仪表盘的Instances格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://admin:123456@eureka1.com:8762/eureka/,http://admin:123456@eureka2.com:8762/eureka/,http://admin:123456@eureka3.com:8763/eureka/
#从eureka服务器注册表中获取注册表信息的时间间隔,默认30s
registry-fetch-interval-seconds: 30
#客户端发送变化同步到eureka服务器的时间间隔 默认30s
instance-info-replication-interval-seconds: 30
#询问eureka服务url信息的变化的间隔时间 默认300s
eureka-service-url-poll-interval-seconds: 300
#最初同步到eureka服务器的时间 默认40s
initial-instance-info-replication-interval-seconds: 40
#注册表是否压缩
g-zip-content: true
#eureka等待超时时间 默认是5s
eureka-server-connect-timeout-seconds: 5
#eureka等待读取时间 默认是8s
eureka-server-read-timeout-seconds: 8
#eureka客户端允许的所有eureka服务器连接的总数 默认200
eureka-server-total-connections: 200

3:启动类中开启Feign支持

@@EnableEurekaClient

@EnableFeignClients

package com.applesnt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //开启feign支持
public class MhbCloudConsumerFeignApplication { public static void main(String[] args) {
SpringApplication.run(MhbCloudConsumerFeignApplication.class, args);
}
}

4:构建Feign远程调用接口

@FeignClient(name = "mhb-cloud-producer",configuration = FeignClientsConfiguration.class)

com\applesnt\service\FeignClientService.java

package com.applesnt.service;

import com.applesnt.vo.UserVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/*
name:提供者的服务名称
configuration:使用默认配置类 FeignClientsConfiguration
默认配置支持springmvc注解
*/
@FeignClient(name = "mhb-cloud-producer",configuration = FeignClientsConfiguration.class)
public interface FeignClientService { /*value要写全路径
* PathVariable一定要指定value值
* */
@GetMapping("/producer/get/{id}")
public String getId(@PathVariable("id") String id); @GetMapping("/producer/getuserbyid/{id}")
public UserVo getUserById(@PathVariable("id") String id); @GetMapping("/producer/getuser2")
public UserVo getUser2(@RequestParam("id") String id,
@RequestParam("name") String name); /*
* 如果传入复杂(vo类型)参数时 不支持get请求 远程调用对象必须要用post请求
* 所以getUser3是调用失败的
* */
@GetMapping("/producer/getuser3")
public UserVo getUser3(UserVo userVo); /*POST请求 如果是复杂对象 可以使用@RequestBody 也可以不使用*/
@PostMapping("/producer/getuser")
public UserVo getUser(@RequestBody UserVo userVo); @GetMapping("/producer/getlist")
public List<UserVo> getUserList();
}

5:构建远程调用controller

【构建UserVo对象】com\applesnt\vo\UserVo.java

package com.applesnt.vo;
import lombok.Data; @Data
public class UserVo { private String user_id; private String user_name; private String code; public UserVo(String user_id, String user_name, String code) {
this.user_id = user_id;
this.user_name = user_name;
this.code = code;
} public UserVo() {
}
}

【构建远程调用Controller】com\applesnt\controller\FeignConsumerController.java

package com.applesnt.controller;

import com.applesnt.service.FeignClientService;
import com.applesnt.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List; @RestController
@RequestMapping("/feign")
@Slf4j
public class FeignConsumerController { @Autowired/*feign远程服务接口注入*/
private FeignClientService feignClientservice; @GetMapping("/get/{id}")
//http://127.0.0.1:8801/feign/get/123
public String getId(@PathVariable("id") String id){ String reutrnStr = feignClientservice.getId(id);
log.info("feign调用 = {}",reutrnStr); return reutrnStr;
} @GetMapping("/getuserbyid/{id}")
//http://127.0.0.1:8801/feign/getuserbyid/123
public UserVo getUserById(@PathVariable("id") String id){ UserVo userVo = feignClientservice.getUserById("123");
log.info("feign调用 = {}",userVo); return userVo;
} @GetMapping("/getuser2")
//http://127.0.0.1:8801/feign/getuser2?id=123&name=zhangsan
public UserVo getUser2(@RequestParam(name = "id",required = false) String id,
@RequestParam("name") String name){ UserVo userVo = feignClientservice.getUser2(id,name);
log.info("feign调用 = {}",userVo); return userVo;
} @GetMapping("/getuser3")
//http://127.0.0.1:8801/feign/getuser3?user_id=123&user_name=zhangsan
public UserVo getUser3(UserVo userVo){ /*feign调用-会报错,不支持get远程调用*/
UserVo uVo = feignClientservice.getUser3(userVo);
log.info("feign调用 = {}",uVo); return uVo;
} @PostMapping("/getuser")
//http://127.0.0.1:8801/feign/getuser【要用postman模拟post请求】
public UserVo getUser(@RequestBody UserVo userVo){ UserVo uVo = feignClientservice.getUser(userVo);
log.info("feign调用 = {}",uVo); return uVo;
} @GetMapping("/getlist")
//http://127.0.0.1:8801/feign/getlist
public List<UserVo> getUserList(){ List<UserVo> list = feignClientservice.getUserList();
log.info("feign调用 = {}",list); return list;
}
}

6:Feign远程调用测试

分别启动Eureka服务集群、mhb-cloud-consumer-feign、mhb-cloud-producer、mhb-cloud-producer-extend六个服务

http://127.0.0.1:8801/feign/getuser2?id=123&name=zhangsan

第一次访问:

第二次访问:

四、Feign调用非微服务

创建远程调用service接口

@FeignClient(name = "xxxx",url = "http://localhost:8761")

com\applesnt\service\FeignClientService2.java

package com.applesnt.service;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.*; /*不写configuration属性 默认使用FeignClientsConfiguration
* 默认配置支持springmvc注解
* */
@FeignClient(name = "xxxx",url = "http://localhost:8761")
public interface FeignClientService2 { @GetMapping(value = "/eureka/apps")
public String getapp(); }

在FeignConsumerController中追加远程调用方法:


@Autowired/*feign远程服务接口注入(非微服务)*/
private FeignClientService2 feignClientService2; /*访问非微服务*/
//http://127.0.0.1:8801/feign/getapp
@GetMapping("/getapp")
public String getapp(){
String reutrnStr = feignClientService2.getapp();
return reutrnStr;
}

五、Feign日志配置

由于Feign默认不开启日志,所有我们要创建一个配置类用于覆盖默认配置

com\applesnt\config\FeignLogConfiguration.java

package com.applesnt.config;

import feign.Logger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class FeignLogConfiguration { @Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}

2:在feign的远程调用service接口中,配置上FeignLogConfiguration类

@FeignClient(name = "mhb-cloud-producer",configuration = FeignLogConfiguration.class)

3:在application.yml中开启service接口的日志输出

logging:
level:
com.applesnt.service.FeignClientService: debug

4:日志输出

SpringCloud(四)学习笔记之Feign的更多相关文章

  1. springcloud Eureka学习笔记

    最近在学习springcloud,抽空记录下学习笔记;主要记录Eureka的实现过程和高可用性的实现 Eureka是一个服务治理框架,它提供了Eureka Server和Eureka Client两个 ...

  2. SpringCloud Alibaba学习笔记

    目录 目录 目录 导学 为什么学 学习目标 进阶目标 思路 Spring Cloud Alibaba的重要组件 环境搭建 Spring Boot必知必会 Spring Boot特性 编写第一个Spri ...

  3. springcloud Ribbon学习笔记二

    之前介绍了如何搭建eureka服务并开发了一个用户服务成功注册到了eureka中,接下来介绍如何通过ribbon来从eureka中获取用户服务: springcloud ribbon提供客户端的负载均 ...

  4. SpringCloud(六)学习笔记之Zuul

    Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门 Hystrix+Ribbon(不使用Feign) ...

  5. SpringCloud(五)学习笔记之Hystrix

    在微服务架构中多层服务之间会相互调用,如果其中有一层服务故障了,可能会导致一层服务或者多层服务故障,从而导致整个系统故障.这种现象被称为服务雪崩效应. Hystrix组件就可以解决此类问题,Hystr ...

  6. springcloud Zuul学习笔记

    SpringCloud Zull是一个基于NetflixZuul实现的API网关组件,它实现了请求路由,负载均衡,校验过滤等功能;本文主要记录springcloud zuul的入门级demo开发过程; ...

  7. springcloud Ribbon学习笔记一

    上篇已经介绍了如何开发eureka服务并让多个服务进行相互注册,接下来记录如何开发一个服务然后注册到eureka中并能通过ribbon成功被调用 开发一个用户服务并注册到eureka中,用户服务负责访 ...

  8. spring cloud学习笔记三 Feign与Ribbon负载均衡的区别

    一.Feign的介绍 Feign一般比较书面的解释是:Feign是一个声明式的WebService客户端,使用Feign编写的WebService客户端更加简单,他的使用方法是定义一个接口,然后在上线 ...

  9. SpringCloud(三)学习笔记之Ribbon

    spring Cloud Ribbon 是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制. 客户端负载均衡即是当浏览器向后台发出请求的时候,客户端会向 Eureka Serve ...

随机推荐

  1. WEB缓存控制机制与varnish简介

    在说到缓存varnish前,我们首先来了解下对于web服务缓存到底是什么?它有哪些特点,基础原理是什么? http是web应用协议,通常我们说的一次http事务,不外乎就是客户端请求,服务端响应,通常 ...

  2. 编译原理:DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题   解析: 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 解析: S→ 0A|1B →S → 0(1S|1)|1(0S|0 ...

  3. SublimeのJedi (自动补全)

    关于 Sublime 3 - Jedi Package 的设置和使用方法 我是一枚小白,安装后 Sublime 后,想在码字时,达到如下效果: 打字时,自动提示相关内容 按Tab键,相关内容自动填充 ...

  4. Failed RMAN Catalog Upgrade from 11.2.0.2 to 12.1.0.2 ( ORA-02296 RMAN-06004 )

    Failed RMAN Catalog Upgrade from 11.2.0.2 to 12.1.0.2  ( ORA-02296  RMAN-06004 ) 由于后期使用12c的数据库,需要对现有 ...

  5. sql MYSQL主从配置

    MYSQL主从配置 1.1 部署环境 主(master_mysql): 192.168.1.200 OS:CentOS 6.5 从(slave_mysql): 192.168.1.201 OS:Cen ...

  6. Luogu1039 侦探推理

    题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...

  7. Java 程序该怎么优化?(技巧篇)

    搬砖者:为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了? 面试官:简单谈谈 Java 程序性能优化? 1. 字符串处理优化,乃优化之源. 研发过程中,String 的 API 用的应该是 ...

  8. python爬虫之requests的高级使用

    1.requests能上传文件 # 导入requests模块 import requests # 定义一个dict files = {'file': open('D:/360Downloads/1.t ...

  9. 1014 Waiting in Line (30 分)

    Suppose a bank has N windows open for service. There is a yellow line in front of the windows which ...

  10. 微信小程序之界面交互反馈

    交互反馈就是在用户出发某事件之后,给用户一个反馈信息,这要是一个很友好的习惯. 在小程序中是通过一下几种方式实现的: 1.wx.showToast()方法 showToast: function (p ...