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