sringcloud2.0学习-10- 声明式服务调用SpringCloud Feign

声明式服务调用SpringCloud Feign

springcloud有两种接口调用方式,一种是通过RestTemplate,像下面这样调用:

restTemplate.getForObject("http://app-member/getmember", String.class);

个人理解,这种方式将接口的调用与业务代码掺杂在一起,不太友好,基本不用。
另一种是Feign客户端调用,Fegin采用接口加注解的方式实现,易读性较强。

1.Feign简介

Feign客户端是一个web声明式http远程调用工具,提供了接口和注解方式进行调用。

2. Feign的使用

创建一个父工程,然后再分别创建三个Module:Eureka Server ,memberService 和 orderService,并关闭eureka自我保护

2.1父工程搭建
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>com.lchtestgroupId>
  <artifactId>springcloud2.0-eureka-selfprotectartifactId>
  <version>0.0.1-SNAPSHOTversion>
  <packaging>pompackaging>
  
   <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.0.3.RELEASEversion>
    parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>Finchley.RELEASEversion>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
    <modules>
    	<module>eureka-servermodule>
    	<module>springcloud2.0-eureka-selfprotect-eurekaservermodule>
    	<module>springcloud2.0-eureka-selfprotect-ordermodule>
    	<module>springcloud2.0-eureka-selfprotect-membermodule>
    modules>
project>
2.2 EurekaServer模块搭建
  • pom引入spring-cloud-starter-netflix-eureka-server 依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <parent>
    <groupId>com.lchtestgroupId>
    <artifactId>springcloud2.0-eureka-selfprotectartifactId>
    <version>0.0.1-SNAPSHOTversion>
  parent>
  <artifactId>springcloud2.0-eureka-selfprotect-eurekaserverartifactId>
  <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>
    dependencies>
  
project>
  • yaml配置,关闭Eureka自我保护
server:
  port: 8100

eureka:
  instance:
  #注册中心ip地址
    hostname: 127.0.0.1
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
    # 不将自己注册到注册中心 
    register-with-eureka: false
    fetch-registry: false
  server:
    # 关闭自我保护机制,保证服务不可用时及时剔出
    enable-self-preservation: false
    # 踢出失效服务的间隔
    eviction-interval-timer-in-ms: 2000
  • 启动类 @EnableEureakServer开启注册中心
package com.lchtest.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
//@EnableEureakServer表示开启注册中心
@EnableEurekaServer
public class AppEurekaServer {
	public static void main(String[] args) {
		SpringApplication.run(AppEurekaServer.class, args);
	}
}
2.3 MemberService搭建
  • pom
    引入spring-cloud-starter-netflix-eureka-client 依赖和springboot-web组件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <parent>
    <groupId>com.lchtestgroupId>
    <artifactId>springcloud2.0-eureka-selfprotectartifactId>
    <version>0.0.1-SNAPSHOTversion>
  parent>
  <artifactId>springcloud2.0-eureka-selfprotect-memberartifactId>
  
   <dependencies>
          
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
         dependency>
         
        <dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
    dependencies>
project>
  • yaml
    配置注册中心地址并设置客户端心跳检测时间
# 会员服务项目端口号
server:
  port: 8070
# 服务别名--服务注册到注册中心的名称
spring:
  application:
    name: app-member
eureka:
  client:
    service-url:
      #将当前服务注册到eureka注册中心
      defaultZone: http://localhost:8100/eureka/
    # 将自己注册到注册中心,设置为true
    register-with-eureka: true
    # 检索服务信息
    fetch-registry: true
  # eureka客户端与eureka服务端心跳检测及续约时间,本地开发时设置小些,保证服务不可用时就踢出
  instance:
    # eureka客户端向服务端发送心跳的时间间隔,单位为秒
    lease-renewal-interval-in-seconds: 1
    # eureka服务端在收到最后一次心跳检测之后等待的事件上限,单位为秒,超过此时间则剔除
    lease-expiration-duration-in-seconds: 2     
  • 启动类:
    使用@EnableEurekaClient注解将member服务注册到注册中心
package com.lchtest.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class AppMember {

	public static void main(String[] args) {
		SpringApplication.run(AppMember.class, args);
	}
}
  • MemberController
package com.lchtest.springcloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MemberController {
	
	@Value("${server.port}")
	private String port;
	
	@RequestMapping("/member/getmember")
	public String getMemberByFeign() {
		return "member service port=" + port;
	}
}
2.4 OrderService搭建
  • pom依赖
    集成Feign客户端spring-cloud-starter-openfeign 和springboot-web组件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <parent>
    <groupId>com.lchtestgroupId>
    <artifactId>springcloud2.0-eureka-selfprotectartifactId>
    <version>0.0.1-SNAPSHOTversion>
  parent>
  <artifactId>springcloud2.0-eureka-selfprotect-orderartifactId>
  
   <dependencies>
               
          
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
         dependency>
         
        <dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		
		 
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
    dependencies>
project>
  • 配置文件
# 会员服务项目端口号
server:
  port: 8001
# 服务别名--服务注册到注册中心的名称
spring:
  application:
    name: app-order
eureka:
  client:
    service-url:
      #将当前服务注册到eureka注册中心
      defaultZone: http://localhost:8100/eureka/
    # 将自己注册到注册中心,设置为true
    register-with-eureka: true
    # 检索服务信息
    fetch-registry: true
  # eureka客户端与eureka服务端心跳检测及续约时间,本地开发时设置小些,保证服务不可用时就踢出
  instance:
    # eureka客户端向服务端发送心跳的时间间隔,单位为秒
    lease-renewal-interval-in-seconds: 1
    # eureka服务端在收到最后一次心跳检测之后等待的事件上限,单位为秒,超过此时间则剔除
    lease-expiration-duration-in-seconds: 2
  • Feign客户端接口定义
package com.lchtest.springcloud.feignclient;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 声明式Feign客户端调用服务
 * @author pc
 */
@FeignClient(value = "app-member")
public interface MemberFeign {

	@RequestMapping("/member/getmember")
	public String getmember();
}

@FeignClient(value = “app-member”) ,@FeignClient代表一个Feign客户端,value的值是该客户端要调用的服务在注册中心里的名称
@RequestMapping("/member/getmember") 就是rpc方式要调用的远程接口/member/getmember,是服务提供者对外暴露的接口
猜测FeignClient注解本质上应该是通过反射获取到注解的值,拿到要调用的服务的名称,然后去注册中心获取到服务对应的地址信息,然后再根据@RequestMapping注解
的值组装接口调用地址,最后以HttpClient方式去调用

  • Controlelr
    controller中注入Feign客户端接口的实例MemberFeign,调用对应方法即可
package com.lchtest.springcloud.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lchtest.springcloud.feignclient.MemberFeign;

@RestController
@RequestMapping("/orderfeign")
public class FeignClientTestController {
	@Autowired
	private MemberFeign memberFeign;
	
	/**
	 * 通过feign客户端调用member服务:http://localhost:8001/orderfeign/getmemberByFeign  
	 * @return
	 */
	@RequestMapping("/getmemberByFeign")
	public String getmember() {
		return "通过Feign客户端调用member服务,响应是:" + memberFeign.getmember();
	}
}
  • 主启动类 需要加上@EnableFeignClients注解启用feign客户端
package com.lchtest.springcloud;

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.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients // 启用feign客户端
public class AppOrder {

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

Feign客户端使用步骤总结

  1. 使用Feign客户端的项目集成Feign客户端
 <dependency>
       <groupId>org.springframework.cloudgroupId>
       <artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
  1. Feign客户端接口定义
    接口类名上面加上注解@FeignClient(value = “app-member”) 来声明Feign客户端,并指定要调用的微服务在注册中心注册的名称,@RequestMapping指定要调用的接口方法:
@FeignClient(value = "app-member")
public interface MemberFeign {
	@RequestMapping("/member/getmember")
	public String getmember();
}
  1. 使用Feign客户端的地方注入Feign客户端接口并调用
// 注入
@Autowired
private MemberFeign memberFeign;
// 接口调用
memberFeign.getmember();
  1. 启动类加上@EnableFeignClients 注解启用Feign客户端

当前Feign客户端调用缺点sringcloud2.0学习-10- 声明式服务调用SpringCloud Feign_第1张图片

可以看到,order服务要通过Feign客户端调用member服务的/member/getmember接口,就必须在order服务中定义一个相同的Feign客户端接口,如果有很多个接口,这样的重复代码就很多了,因此这样的项目结构不是很合理。

点击下载代码
参见springcloud2.0-eureka-selfprotect 工程

你可能感兴趣的:(SpringCloud2.0)