SpringCloud-Ribbon

       spring-cloud-starter-netflix-eureka-client 3.0以上默认不再集成Ribbon而改为集成spring-cloud-starter-loadbalancer。这里只是简单介绍一下之前的ribbon使用。

1.Ribbon介绍

       Ribbon是基于HTTO和TCP协议的,主要功能是实现客户端软件的负载均衡算法

       Spring Cloud中Ribbon就是基于NetFix公司的Ribbon实现的,不需要单独部署,但是却存在于整个微服务中。前面学习的Eureka里面有Ribbon,后面学习的OpenFeign也是基于RibbOn实现的。

2.Ribbon原理

       所有的项目都会注册到Eureka中,Eureka允许不同项目的spring.application.name相同。当相同时会认为这些项目一个集群,所以同一个项目部署多次时都是设置应用程序名相同。

Application Client会从Eureka中根据spring.application.name加载Application Service的列表。根据设定的负载均衡算法,从列表中取出一个URL,到此Ribbon事情就结束了

下面的事情就是由程序员自己进行技术选型,选择一个HTTP协议工具,通过这个URL调用Application Service。

3.负载均衡分类

3.1集中式负载均衡

       在客户端和服务端中间使用独立的负载均衡设施,有硬件的(比如 F5),也有软件的(比如 Nginx)。由该设施负责把访问请求通过某种策略转发至服务端。也叫服务端负载均衡。

 

3.2进程内负载均衡

     将负载均衡逻辑集成到客户端组件中客户端组件从服务注册中心获取有哪些地址可用,然后自己再从这些地址中选择一个合适的服务端发起请求Ribbon就是一个进程内的负载均衡实现。也叫客户端负载均衡。

4.搭建Application Service集群

       创建好Eureka注册中心(端口8761)和服务提供者(端口9090)

       另外再多开两个服务提供者主类,端口设置为9091---9092,使用编辑配置比较快,否则也可以自己多创建2个模块,写一样的代码。

 

服务消费者

在这里选择springboot版本为2.3.7.RELEASE,创建spring模块的时候,更改服务器URL为ailiyun.com。因为spring.io里面都是最新版本的springboot。

spring-cloud-starter-netflix-eureka-client 3.0以上默认不再集成Ribbon而改为集成spring-cloud-starter-loadbalancer。

 

 

查看依赖项

2.3.7版本的springboot匹配2.2.6版本的eureka,里面包含有ribbon

application.properties

# 应用名称
spring.application.name=consumer
# 应用服务 WEB 访问端口
server.port=8080

eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

 

主类加上@EnableEurekaClient注解

控制类

@RestController
public class
ConsumerController {
   
@Autowired
    private
ConsumerService consumerService;
   
@RequestMapping("/consumer")
   
public String consumer(){
       
return consumerService.client();
   
}
}

接口和接口实现类

package com.weiwei.consumer1.service;

public interface ConsumerService {
   
String client();
}

package com.weiwei.consumer1.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;

@Service
public class
ConsumerServiceImpl implements ConsumerService{
   
@Autowired
   
//ribbon的负载均衡工具
   
private LoadBalancerClient loadBalancerClient;
   
@Override
    public
String client() {

       //loadBalancerClient.choose("服务提供者的spring.application.name");

        ServiceInstance serviceInstance = loadBalancerClient.choose("provide");

        //得到被调用提供者的Url和端口号,清楚分给了哪个服务端

System.out.println("Url===="+serviceInstance.getUri()+"Port===="+serviceInstance.getPort());
       
return null;
   
}
}

浏览器访问localhost:8080/consumer

 

 

可以发现,ribbon负载均衡是轮循规则。

5.RestTemplate

       RestTemplate是spring-web-xxx.jar包中提供的Http协议实现类。导入spring-web-xxx.jar包就可以直接使用RestTemplate类。

在该类中有主要针对6类请求方式封装的方法。

Http method

RestTemplate method

DELETE

delete

GET

getForObject

getForEntity

POST

postForObject

postForLocation

HEAD

headForHeaders

PUT

put

OPTIONS

optionsForAllow

any(不管什么协议)

万能的

exchange

execute

5.1发Get请求

请求参数方式1:

@RequestMapping("/demo2")
public String demo2(String name, Integer age) {
   
return "name:" + name + "age:" + age;
}

对应测试类:

@Test
void
test2() {
   
RestTemplate restTemplate = new RestTemplate();
   
String result = restTemplate.getForObject("http://localhost:8080/demo2?name=zhangsan&age=12", String.class);
   
System.out.println(result);
}

@Test
void
test3() {
   
String name="zhangsan";
   
Integer age=23;
   
RestTemplate restTemplate = new RestTemplate();
   
//地址使用字符串拼接方式传参数,这样容易写错
   
//String result = restTemplate.getForObject("http://localhost:8080/demo2?name="+name+"&age="+age, String.class);
    //
新写法使用占位符,第三个参数往后赋值
   
String result = restTemplate.getForObject("http://localhost:8080/demo2?name={1}&age={2}", String.class,name,age);
   
System.out.println(result);
}
@Test
void
test4() {
   
//使用map方式
   
RestTemplate restTemplate = new RestTemplate();
   
HashMap<String, Object> map = new HashMap<>();
   
map.put("name","lisisi");
   
map.put("age",23);
   
String result = restTemplate.getForObject("http://localhost:8080/demo2?name={name}&age={age}", String.class,map);
   
System.out.println(result);
}

请求参数方式2:

@RequestMapping("/demo3/{name}/{age}")
public String demo3(@PathVariable String name,@PathVariable Integer age) {
   
return "name:" + name + "age:" + age;
}

对应测试类:

@Test
void
test11() {
   
RestTemplate restTemplate = new RestTemplate();
   
String result = restTemplate.getForObject("http://localhost:8080/demo3/zhangsan/22", String.class);
   
System.out.println(result);
}
@Test
void
test12() {
   
String name="zhangsan";
   
Integer age=23;
   
RestTemplate restTemplate = new RestTemplate();
   
String result = restTemplate.getForObject("http://localhost:8080/demo3/{1}/{2}", String.class,name,age);
   
System.out.println(result);
}

@Test
void
test13() {
   
//使用map方式
   
RestTemplate restTemplate = new RestTemplate();
   
HashMap<String, Object> map = new HashMap<>();
   
map.put("name","lisisi");
   
map.put("age",23);
   
String result = restTemplate.getForObject("http://localhost:8080/demo3/{name}/{age}", String.class,map);
   
System.out.println(result);
}

getForEntity()区别在返回值

@Test
void
test21() {
   
RestTemplate restTemplate = new RestTemplate();
   
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8080/demo2?name=zhangsan%age=234", String.class);
   
System.out.println(entity.getStatusCode());
   
System.out.println(entity.getStatusCodeValue());
   
System.out.println(entity.getBody());
   
System.out.println(entity.getHeaders());

}

输出:

200 OK

200

name:zhangsan%age=234age:null

[Content-Type:"text/plain;charset=UTF-8", Content-Length:"29", Date:"Tue, 12 Apr 2022 17:27:22 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]

5.2发Post请求

 

发post请求一般是传递请求体数据


@RequestMapping("/demo4")
public String demo3(String name, Integer age, @RequestBody HashMap<String,Object> map) {
   
System.out.println(map);
   
return "name:" + name + "age:" + age;
}

@Test
void
PostForObject1(){
   
HashMap<String, Object> map = new HashMap<>();
   
map.put("name","zhangsan");
   
map.put("age",33);
   
RestTemplate restTemplate = new RestTemplate();
   
String result = restTemplate.postForObject("http://localhost:8080/demo4?name=zhangsan&age=234", map, String.class);
   
System.out.println(result);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java-请多指教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值