Feign负载均衡


  Feign是一个声明式的Web Service客户端,比Ribbon好用,默认也是轮巡。我们只需要使用Feign创建一个接口,并用注解就好了。如果你基于spring cloud发布一个接口,实际上就是支持http协议的,对外发布的就是一个最普通的mvc的http接口。我们使用feign注解,实际上它会对这个接口生成动态代理,从eureka的readonly中拿到其他服务信息、进行http请求调用。

feign案例编写:

1. 导包

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version> 
        <relativePath/>
    </parent>
    <!-- springcloud依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- eureka客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!-- feign客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>

2. 配置application.yml文件 

# 项目访问路径前缀
server:
  context-path: /feign
  port: 8085

# 设置服务名称,服务会以这个名字注册到eureka服务器上
spring:
  application:
    name: feign

# 设置eureka服务器的注册地址
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/


#ribbon的超时时间, 防止feign调用超时
ribbon:
  ReadTimeout: 15000
  ConnectTimeout: 15000
  MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
  MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
  OkToRetryOnAllOperations: false  #是否所有操作都重试 

3. 主函数入口开启eureka和feign客户端

@SpringBootApplication
@EnableEurekaClient//开启eureka
@EnableFeignClients//开启feign
public class FeignMain {

    public static void main(String[] args) {
        new SpringApplicationBuilder(FeignMain.class).web(true).run(args);
    }
}

4. 调用接口

@RestController
public class UserController {
    
    @Autowired
    private UserService userService;

    @RequestMapping("/test")
    public Map test() {
        return userService.test("张三");
    }
    
    @RequestMapping("/testObj")
    public User testObj() {
        return userService.testObj(new User());
    }
}

5. 编写feign调用的服务层。

import java.util.Map;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.model.User;
//name 目标的服务名    目标的url前缀
@FeignClient(name ="demo",path="/demo")
public interface UserService {
    
    // 调用police服务的testOut接口
    @RequestMapping("/testOut")
    public Map test(@RequestParam("name") String name);
    
    // 调用police服务的testOutObj接口
    @RequestMapping("/testOutObj")
    public User testObj(@RequestBody User user);
}

feign客户端就开发完成了; 我们来看看提供服务的另一个项目的接口。

@RestController
public class MyController {

    @RequestMapping("/testOut")
    public Map test(@RequestParam("name") String name,HttpServletRequest req) {
        Map m = new HashMap<>();
        m.put("url", req.getRequestURL().toString());
        m.put("name", name);
        try {
            Thread.sleep(16000);
        } catch (InterruptedException e) {
        }
        return m;
    }
    
    @RequestMapping("/testOutObj")
    public User testObj(@RequestBody() User user,HttpServletRequest req) {
        user.setUrl(req.getRequestURL().toString());
        try {
            Thread.sleep(14000);
        } catch (InterruptedException e) {
        }
        return user;
    }
}

测试: 由于超时时间设置的15s, 而两个接口分别阻塞14s ,16s ,所以第二个接口会超时报错。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM