微服务调用ribbon与feign

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。

参考文档:http://cloud.spring.io/spring-cloud-static/Dalston.SR5/single/spring-cloud.html#spring-cloud-ribbon 第16节

项目环境:https://blog.csdn.net/wufewu/article/details/84646382

                                                                    Ribbon调用

Main方法处添加负载均衡

@Bean
RestTemplate restTemplate() {
	return new RestTemplate();
}

                                                                    RestTemplate的用法

RestTemplate的四种请求:

GET请求    getForEntity
POST请求  postForEntity
PUT请求    put
DELETE请求  delete

客户端请求:

Book book = new Book(); 
book.setName(“红楼梦”);
ResponseEntity<Book> responseEntity = restTemplate.postForEntity(“http://服务名/路径", book, Book.class);
return responseEntity.getBody();

服务端接收

@PostMapping(value = "/getbook2")
public Book book2(@RequestBody Book book) {}

其中具体的例子可以查看:https://blog.csdn.net/wufewu/article/details/84646382 里面的SPRINGCLOUD_USERUI模块


在这里插入图片描述
其中默认的是RoundRobinRule(轮循查询),如果想要更改算法,直接在Main方法添加一个Bean类,如:

@Bean
        // 支持负载均衡功能(默认使用Ribbon实现负载均衡)
        @LoadBalanced
        public RestTemplate restTemplate(){
                return new RestTemplate();
        }
    // 指定负载均衡算法
    // 所有调用的微服务都想是同一个规则就放在这里
    // 全局配置
    @Bean
    public RandomRule randomRule() {
    	return new RandomRule();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(UserUi.class).web(true).run(args);
    }<strong>解释</strong>:我将负载均衡算法改为了一个RandomRule算法(随机算法),<br>

模拟环境:在注册中心建立一个微服务的两个实例,然后在客户端建立一个调用微服务的方法的方法,然后输出结果。这里就不展示了

注意:在Main方法里更改算法,所有的调用微服务的算法都会变成更改后的算法

建立自定义的负载均衡规则:

      定义规则类

package com.ps.rule;

import java.util.List;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
public class MyRule extends AbstractLoadBalancerRule{

	@Override
	public Server choose(Object key) {
		// 取到当前的负载均衡器,由父类提供 可以拿到对应的要调用微服务后的服务器
		ILoadBalancer loadBalancer = this.getLoadBalancer();
		// 取到所有可以访问的服务器
		List<Server> reachableServers = loadBalancer.getReachableServers();
		return reachableServers.get(0);
	}
	@Override
	public void initWithNiwsConfig(IClientConfig arg0) {
		// TODO Auto-generated method stub
	}
}

然后在Main方法指定算法:

 @Bean
 public IRule rhle() {
   	return new MyRule();
 }

   
   
  • 1
  • 2
  • 3
  • 4

解释:在这里调用微服务的实例只能调用第一个


当调用微服务不使用全局配置,即调用指定的微服务时是随机,调用其他的微服务是默认(轮徇)的
自定义类:

@RibbonClient(value="USERSERVICE",configuration=MyRule.class)
public class MyRule {
@Bean
public IRule randomRul() {
	return new RoundRobinRule();
}

然后在application.yml资源文件中加:

# 放在这里是指针对不同的微服务调用不同的负载均衡规则
USERSERVICE: 
  ribbon: 
   NFLoadBalancerRuleClassName: com.ps.rule.MyRule

解释:
          USERSERVICE:指微服务的名字
          com.ps.rule.MyRule:指定义的类的路径



二.Feign简介


Feign是从Netflix中分离出来的轻量级项目,能够在类接口上添加注释,成为一个REST API 客户端,(面向对象,更优雅,更适合普通的开发者人员)
参考文档:http://cloud.spring.io/spring-cloud-static/Dalston.SR5/single/spring-cloud.html#spring-cloud-feign 第17节
项目环境:https://blog.csdn.net/wufewu/article/details/84646382

我现在根据项目环境来演示一下feign的调法,查看项目环境中的SPRINGCLOUD_USERSERVICE模块,添加一个EmpController.java与一个实体类,如下:
在这里插入图片描述
代码如下:
EmpController.java

package com.ps.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.ps.entity.Emp;
import com.ps.entity.Result;

@RestController
public class EmpController {
	@GetMapping("/emp/{id}")
	 public Result queryEmp(@PathVariable("id") String id) {
		 Emp emp = new Emp();
		 emp.setId("1");
		 emp.setName("张三");
		 Result re = new Result();
		 List<Emp> list = new ArrayList<>();
		 list.add(emp);
		 re.setCode(1);
		 re.setData(list);
		 return re;
	 }
	 
	// post请求因为参数带有对象,所以必须添加@RequestBody
	 @PostMapping("/emp")
	 public Result saveEmp(@RequestBody Emp emp) {
		 Result re = new Result();
		 re.setCode(1);
		 re.setMsg("增加应该成功了");
		 return re;
	 }
	 
	 @DeleteMapping("/emp/{id}")
	 public Result delEmp(@PathVariable String id) {
		 Result re = new Result();
		 re.setCode(1);
		 re.setMsg("删除应该成功了");
		 return re;
	 }
	 
	 @PutMapping("/emp/{id}")
	 public Result delEmp(@PathVariable String id,@RequestBody Emp emp) {
		 Result re = new Result();
		 re.setCode(1);
		 re.setMsg("修改应该成功了");
		 return re;
	 }
}

@Data
public class Emp {
	private String id;
	private String name;
}

    
    
  • 1
  • 2
  • 3
  • 4
  • 5




然后再在项目中加一个模块(方便演示)SPRINGCLOUD_USERUI_FEIGN,如:

在这里插入图片描述
在pom.xml文件添加依赖:

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!-- 小辣椒 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <scope>provided</scope>
        </dependency>
        <!-- 开发者工具 -->
        <dependency>   
			<groupId>org.springframework.boot</groupId>    
			<artifactId>spring-boot-devtools</artifactId>     
			<optional>true</optional>    
		</dependency>
		<!-- 导入Feign依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
    </dependencies>

application.yml资源文件:

#界面一般是80端口
server:
  port: 80

#给登录微服务设置一个名字
spring:
application:
name: useruifeign

eureka:
instance:
prefer-ip-address: true
hostname: localhost
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/

entity包下的两个实体类:
Emp.java:

@Data
public class Emp {
	private String id;
	private String name;
}

Result.java

@Data
public class Result {
    private int code;
    private String msg;
    private List<Emp> data;
}

EmpFeign.java

// 客户端的接口根远程service做了绑定,假如在这个类跳用queryEmp方法就相当与调用远程微服务

// 指定要调用的微服务
@FeignClient(name=“USERSERVICE”)
public interface EmpFeign {
@GetMapping("/emp/{id}")
public Result queryEmp(@PathVariable(“id”) String id) ;

 @PostMapping("/emp")
 public Result saveEmp(@RequestBody Emp emp) ;
 
 @DeleteMapping("/emp/{id}")
 public Result delEmp(@PathVariable("id") String id) ;
 
 @PutMapping("/emp/{id}")
 public Result delEmp(@PathVariable("id") String id,@RequestBody Emp emp) ;

}

UserUiFeing.java

@SpringBootApplication
// 启用eureka的服务
@EnableEurekaClient
// 表示启用Feign
@EnableFeignClients
public class UserUiFeign {
	public static void main(String[] args) {
        new SpringApplicationBuilder(UserUiFeign.class).web(true).run(args);
    }
}

controlloer包下的EmpcController.java

@RestController
public class EmpcController {
	@Autowired
	EmpFeign empFeign;
@GetMapping("/query")
public List&lt;Emp&gt; query() {
	String id = "1";
	Result queryEmp = empFeign.queryEmp(id);
	return queryEmp.getData();
}

@GetMapping("/save")
public String save() {
	Result queryEmp = empFeign.saveEmp(new Emp());
	return queryEmp.getMsg();
}

@GetMapping("/del")
public String del() {
	Result delEmp = empFeign.delEmp("1");
	return delEmp.getMsg();
}

@GetMapping("/aaa")
public String a() {
	String a = empFeign.a();
	return a;
}

}

运行结果:
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq1765911750/article/details/84750006