详解Spring cloud使用Ribbon进行Restful请求

写在前面

本文由markdown格式写成,为本人第一次这么写,排版可能会有点乱,还望各位海涵。
 主要写的是使用Ribbon进行Restful请求,测试各个方法的使用,代码冗余较高,比较适合初学者,介意轻喷谢谢。

前提

  1. 一个可用的Eureka注册中心(文中以之前博客中双节点注册中心,不重要)
  2. 一个连接到这个注册中心的服务提供者
  3. 一个ribbon的消费者

注意:文中使用@GetMapping、@PostMapping、@PutMapping、@DeleteMapping等注解需要升级 spring-boot-starter-parent版本到1.5.9.REALEASE以上(1.3.7.RELEASE版本没有这些注解)

建议:每个微服务应用都有自己的spring-boot-maven-plugin和maven-compiler-plugin并指定jdk编译版本为1.8 ,指定方式如下,pom.xml中添加

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

测试项目构建

Eureka注册中心:参考注册中心的搭建
 服务提供者:参考注册服务提供者
ribbon消费者:参考服务发现与消费

项目搭建完后,记得按照这几个教程中提到的配置hosts文件

为了防止项目中的RequestMapping相同,这里就删除所有的controller类(服务提供者和消费者),接下来我会将每个restful方法都封装成一个类,方便大家查看

Get请求

getForEntity:此方法有三种重载形式,分别为:

  1. getForEntity(String url, Class<T> responseType)
  2. getForEntity(String url, Class<T> responseType, Object... uriVariables)
  3. getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
  4. getForEntity(URI url, Class<T> responseType)

注意:此方法返回的是一个包装对象ResponseEntity<T>其中T为responseType传入类型,想拿到返回类型需要使用这个包装类对象的getBody()方法

getForObject:此方法也有三种重载形式,这点与getForEntity方法相同:

  1. getForObject(String url, Class<T> responseType)
  2. getForObject(String url, Class<T> responseType, Object... uriVariables)
  3. getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
  4. getForObject(URI url, Class<T> responseType)

注意:此方法返回的对象类型为responseType传入类型

为了方便测试,这里分别在服务提供者和服务消费者中提供相同的User类,用于方便测试

package com.cnblogs.hellxz;

/**
 * 用于测试的pojo
 */
public class User {

  private String name;
  private String sex;
  private String phone;
  public User(){}
  public User(String name, String sex, String phone) {
    this.name = name;
    this.sex = sex;
    this.phone = phone;
  }

  public String toString(){
    return "user:{"
        +"name: " + name + ", "
        +"sex: " + sex + ", "
        +"phone: " + phone
        +" }";
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSex() {
    return sex;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }

  public String getPhone() {
    return phone;
  }

  public void setPhone(String phone) {
    this.phone = phone;
  }
}

下边我们在服务提供者处创建一个GetRequestController

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

/**
 * @Author : Hellxz
 * @Description: 服务提供者
 * @Date : 2018/4/18 11:36
 */
@RestController
public class GetRequestController {

  @Autowired
  private DiscoveryClient client; //注入发现客户端

  private final Logger logger = Logger.getLogger(GetRequestController.class);

  /**
   * go straight test
   */
  @GetMapping(value = "/hello")
  public String hello(){
    //获取服务实例,作用为之后console显示效果
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/hello host:"+serviceInstance.getHost()+" service_id:" +serviceInstance.getServiceId());
    return "hello";
  }

  /**
   * parameter test
   */
  @GetMapping(value = "/greet/{dd}")
  public String greet(@PathVariable String dd){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/hello host:"+serviceInstance.getHost()+" service_id:" +serviceInstance.getServiceId());
    return "hello "+dd;
  }

  /**
   * 返回测试对象
   */
  @GetMapping("/user")
  public User getUser(){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/user "+serviceInstance.getHost()+" port:"+serviceInstance.getPort()+" serviceInstanceid:"+serviceInstance.getServiceId());
    return new User("hellxz","male", "123456789");
  }

  /**
   * 根据名称返回对象,这里模拟查数据库操作
   */
  @GetMapping("/user/{name}")
  public User getUserSelect(@PathVariable String name){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/user "+serviceInstance.getHost()+" port:"+serviceInstance.getPort()+" serviceInstanceid:"+serviceInstance.getServiceId());
    if(name.isEmpty()){
      return new User();
    }else if(name.equals("hellxz")){
      return new User("hellxz","male", "123456789");
    }else{
      return new User("随机用户","male", "987654321");
    }
  }
}

接下来我们在服务消费者项目中创建GetRequestController

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author : Hellxz
 * @Description: ribbon消费者应用Controller,get请求
 * @Date : 2018/4/16 15:54
 */
@RestController
public class GetRequestController {

  private Logger logger = Logger.getLogger(GetRequestController.class);

  @Autowired
  //注入restTemplate
  private RestTemplate restTemplate;

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType)
   * T getBody() 以下此方法相同
   */
  @GetMapping(value="/entity/noparam")
  public String noParamGetForEntity(){
    //这里注释掉,因为之前想当然使用了直链访问服务提供者的接口,这样是不会返回结果的,而且会报错
    //return restTemplate.getForEntity("http://localhost:8080/hello",String.class).getBody();
    //使用restTemplate调用微服务接口
    return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody();

  }

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
   */
  @GetMapping("/entity/type")
  public User getForEntityIdentifyByType(){
    //不传参返回指定类型结果
    ResponseEntity<User> entity = restTemplate.getForEntity("http://hello-service/user", User.class);
    User body = entity.getBody();
    logger.info("user:"+body);
    return body;
    //以上可简写为
//    return restTemplate.getForEntity("http://hello-service/user", User.class).getBody();
  }

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
   * 使用占位符对参数进行替换,内部使用String.format方法实现
   */
  @GetMapping(value="/entity")
  //如果接收的参数是使用参数没有使用?有则使用@PathVariable,否则用@RequestParam
  public String getForEntityByQuestionMarkParam(@RequestParam("name") String name){
    //主要测试getEntity方法,这里测试直接传参
    return restTemplate.getForEntity("http://hello-service/greet/{1}", String.class, name).getBody();
  }

  /**
   * getForEntity方法内部会提取map中,以占位符为key的值作为参数回填入url中
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @GetMapping(value="/entity/map/{name}")
  //如果接收的参数是使用参数没有使用?有则使用@PathVariable,否则用@RequestParam
  public String getForEntityByMap(@PathVariable("name") String name){
    //主要测试getEntity方法,这里测试map传参
    Map<String, String> reqMap = new HashMap();
    reqMap.put("name",name);
    return restTemplate.getForEntity("http://hello-service/greet/{name}", String.class,reqMap).getBody();
  }

  /**
   * ResponseEntity<T> getForObject(URI url, Class<T> responseType)
   */
  @GetMapping("/entity/uri")
  public String getForEntityByURI(){
    //使用uri进行传参并访问
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/greet/{name}").build().expand("laozhang").encode();
    URI uri = uriComponents.toUri();
    return restTemplate.getForEntity(uri, String.class).getBody();

  }
  /**
   * T getForObject(String url, Class<T> responseType)
   */
  @GetMapping("/object")
  public User getForObjectWithNoParam(){
    //相比getForEntity方法,获取对象可以省去调用getBody
    return restTemplate.getForObject("http://hello-service/user", User.class);
  }

  /**
   * T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @GetMapping("/object/map")
  public User getForObjectByMap(){
    //使用map传参
    Map<String, String> paramMap = new HashMap<>();
    paramMap.put("name","hellxz");
    return restTemplate.getForObject("http://hello-service/user", User.class, paramMap);
  }

  /**
   * T getForObject(String url, Class<T> responseType, Object... uriVariables)
   */
  @GetMapping("/object/param/{name}")
  public User getForObjectByParam(@PathVariable String name){
    return restTemplate.getForObject("http://hello-service/user/{name}",User.class, name);
  }

  /**
   * T getForObject(URI url, Class<T> responseType)
   */
  @GetMapping("/object/uri/{name}")
  public User getForObjectByURI(@PathVariable String name){
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/user/{name}")
                                        .build().expand(name).encode();
    URI uri = uriComponents.toUri();
    return restTemplate.getForObject(uri,User.class);
  }
}

先启动注册中心,然后通过访问消费者对外提供的接口进行测试,这些都是本人实际操作过的了,这里就不写测试了

Post请求

post请求和get请求都有*ForEntity和*ForObject方法,其中参数列表有些不同,除了这两个方法外,还有一个postForLocation方法,其中postForLocation以post请求提交资源,并返回新资源的URI

postForEntity:此方法有三种重载形式,分别为:

  1. postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
  2. postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
  3. postForEntity(URI url, Object request, Class<T> responseType)

注意:此方法返回的是一个包装对象ResponseEntity<T>其中T为responseType传入类型,想拿到返回类型需要使用这个包装类对象的getBody()方法

postForObject:此方法也有三种重载形式,这点与postForEntity方法相同:

  1. postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
  2. postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
  3. postForObject(URI url, Object request, Class<T> responseType)

注意:此方法返回的对象类型为responseType传入类型

postForLocation:此方法中同样有三种重载形式,分别为:

  1. postForLocation(String url, Object request, Object... uriVariables)
  2. postForLocation(String url, Object request, Map<String, ?> uriVariables)
  3. postForLocation(URI url, Object request)

注意:此方法返回的是新资源的URI,相比getForEntity、getForObject、postForEntity、postForObject方法不同的是这个方法中无需指定返回类型,因为返回类型就是URI,通过Object... uriVariables、Map<String, ?> uriVariables进行传参依旧需要占位符,参看postForEntity部分代码

按照之前的方式,我们分别在提供服务者和消费者的项目中分别创建PostRequestController

如下服务者PostRequestController代码如下:

package com.shunneng.springcloudhelloworld;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
/**
 * @Author : Hellxz
 * @Description:
 * @Date : 2018/4/18 10:21
 */
@RestController
public class PostRequestController {
  private Logger logger = Logger.getLogger(PostRequestController.class);

  /**
   * 接收一个对象再返回回去,postForEntity/postForObject方法通用
   */
  @PostMapping("/user")
  public User returnUserByPost(@RequestBody User user){
    logger.info("/use接口 "+user);
    if(user == null) return new User("这是一个空对象","","");
    return user;
  }

  /**
   * 测试PostForEntity方法的参数,可以直接看输出判断结果了
   */
  @PostMapping("/user/{str}")
  public User returnUserByPost(@PathVariable String str, @RequestBody User user){
    logger.info("/user/someparam 接口传参 name:"+str +" "+user);
    if(user == null) return new User("这是一个空对象","","");
    return user;
  }

  /**
   * 为postForLocation方法返回URI
   */
  @PostMapping("/location")
  public URI returnURI(@RequestBody User user){
    //这里模拟一个url,真实资源位置不一定是这里
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/location")
                                                .build().expand(user).encode();
    URI toUri = uriComponents.toUri();
    //这里不知道是什么问题,明明生成uri了,返回之后好像并没有被获取到
    logger.info("/location uri:"+toUri);
    return toUri;
  }
}

消费端PostRequestController代码:

package com.cnblogs.hellxz;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
/**
 * @Author : Hellxz
 * @Description: Ribbon消费者post请求controller
 * @Date : 2018/4/18 9:47
 */
@RestController
public class PostRequestController {
  private Logger logger = Logger.getLogger(PostRequestController.class);
  @Autowired
  private RestTemplate restTemplate;

  /**
   * ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType)
   * 其中参数url不多说,Object request如果是不是一个HttpEntity对象,会自动转换为HttpEntity对象,视作完整的body来处理;
   * 如果是HttpEntity对象,那么会被直接当做body处理并且包含header内容。
   * 以下对于重写的方法就不多说了,使用方法大体同getForEntity,如果仅是简单post对象,那么使用不带Object...variables或Map variables的方法即可。
   * postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
   * postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
   *
   * 这里详细说下我遇到的坑:
   * 1、其他几个重载方法的最后边的Object...variables和Map variables都是对之前的url进行操作的,
   *   也就是说,在post请求的url中使用占位符进行传参,而如果在url中没有使用占位符,那么这些最后传的参数是无效的!
   * 2、方法中Object request这个对象如果和服务提供者的接收参数类型相同,那么服务提供者仅需使用@RequestBody接收参数即可。
   * 3、如果二者都使用了,这就比较有趣了,需要一边通过@PathVariable注解接收uri中的参数,一边还需要@RequestBody接收对象或RequestParam按字段接收参数!
   * 4、如果报错了,请仔细看看我上边写的三条,并注意服务提供者的参数接收注解的使用等。
   */
  @PostMapping("/entity")
  public User postForEntity(){
    User user = new User("hellxz1","1","678912345");
    ResponseEntity<User> entity = restTemplate.postForEntity("http://hello-service/user/{str}", user, User.class, "测试参数");
    User body = entity.getBody(); //所有restTemplate.*ForEntity方法都是包装类,body为返回类型对象
    return body;
  }

  /**
   * 使用URI传参,测试结果会显示在服务提供者的终端中
   * ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType)
   */
  @PostMapping("/entity/uri")
  public User postForEntityByURI(){
    User user = new User("老张","1","678912345");
    //这里只是将url转成URI,并没有添加参数
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/user")
                                        .build().encode();
    URI toUri = uriComponents.toUri();
    //使用user传参
    User object = restTemplate.postForObject(toUri, user, User.class);
    return object;
  }

  /**
   * 这里测试postForObject方法,需要注意的参数如上述方法的描述,区别只是不需要getBody了,这里就不再累述了
   * postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
   * postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @PostMapping("/object")
  public User postForObject(){
    User user = new User("hellxz2","1","123654987");
    //这里url传1是为了调用服务者项目中的一个接口
    User responseBody = restTemplate.postForObject("http://hello-service/user/1", user, User.class);
    return responseBody;
  }

  /**
   * post请求还有一种:postForLocation,这里也同样有三种重载,除了无需指定返回类型外,用法相同,返回类型均为URI,也就不累述了
   * postForLocation(String url, Object request, Object... uriVariables)
   * postForLocation(String url, Object request, Map<String, ?> uriVariables)
   * postForLocation(URI url, Object request)
   */
  @PostMapping("/location")
  public URI postForLocation(){
    User user = new User("hellxz3","1","987654321");
    URI uri = restTemplate.postForLocation("http://hello-service/location", user);
    //不知道为什么返回来是空,这个方法仅供参考吧,如果知道是什么情况,我会回来改的
    logger.info("/location uri:"+uri);
    return uri;
  }
}

Put请求&&Delete请求

put请求相对于get和post请求方法来的更为简单,其中无需指定put请求的返回类型,当然也没有返回值,也是三种重载,和之前写的基本一致,这里就不想多说了,delete请求和put请求都是没有返回值的,这里再特地重复写也没什么意思,这里先分别列出这两个请求的方法,代码写在一个类中了

put请求方法如下:

  1. put(String url, Object request, Object... uriVariables)
  2. put(String url, Object request, Map<String, ?> uriVariables)
  3. put(URI url, Object request)

delete请求方法如下:

  1. delete(String url, Object... uriVariables)
  2. delete(String url, Map<String, ?> uriVariables)
  3. delete(URI url)

在提供服务者项目中添加PutAndDeleteRequestController,代码如下

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;

/**
 * @Author : Hellxz
 * @Description: 服务提供者 put&delete请求controller
 * @Date : 2018/4/19 14:11
 */
@RestController
public class PutAndDeleteRequestController {

  private Logger logger = Logger.getLogger(PutAndDeleteRequestController.class);

  @PutMapping("/put")
  public void put(@RequestBody User user){
    logger.info("/put "+user);
  }

  @DeleteMapping("/delete/{id}")
  public void delete(@PathVariable Long id){
    logger.info("/delete id:"+id);
  }
}

在提供服务者项目中添加PutAndDeleteRequestController,代码如下

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * @Author : Hellxz
 * @Description: put请求、delete请求,重载的参数与上述demo基本相同,不予列出
 * @Date : 2018/4/19 13:43
 */
@RestController
public class PutRequestController {

  private Logger logger = Logger.getLogger(PostRequestController.class);
  @Autowired
  private RestTemplate restTemplate;

  /**
   * put请求示例,一般put请求多用作修改
   */
  @PutMapping("/put")
  public void put(@RequestBody User user){
    restTemplate.put("http://hello-service/put",user);
  }

  /**
   * delete请求示例
   */
  @DeleteMapping("/del/{id}")
  public void delete(@PathVariable Long id){
    restTemplate.delete("http://hello-service/delete/{1}", id);
  }
}

结语

这篇博文使用markdown写成,第一次写不知道如何将代码块中加入序号以及折叠代码功能,这可能不是一篇好文章,但是写这篇博文写了快两天,有什么好的建议欢迎评论交流,

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 详解spring cloud整合Swagger2构建RESTful服务的APIs
(0)

相关推荐

  • 详解spring cloud整合Swagger2构建RESTful服务的APIs

    前言 在前面的博客中,我们将服务注册到了Eureka上,可以从Eureka的UI界面中,看到有哪些服务已经注册到了Eureka Server上,但是,如果我们想查看当前服务提供了哪些RESTful接口方法的话,就无从获取了,传统的方法是梳理一篇服务的接口文档来供开发人员之间来进行交流,这种情况下,很多时候,会造成文档和代码的不一致性,比如说代码改了,但是接口文档没有改等问题,而Swagger2则给我们提供了一套完美的解决方案,下面,我们来看看Swagger2是如何来解决问题的. 一.引入Swag

  • 详解Spring cloud使用Ribbon进行Restful请求

    写在前面 本文由markdown格式写成,为本人第一次这么写,排版可能会有点乱,还望各位海涵.  主要写的是使用Ribbon进行Restful请求,测试各个方法的使用,代码冗余较高,比较适合初学者,介意轻喷谢谢. 前提 一个可用的Eureka注册中心(文中以之前博客中双节点注册中心,不重要) 一个连接到这个注册中心的服务提供者 一个ribbon的消费者 注意:文中使用@GetMapping.@PostMapping.@PutMapping.@DeleteMapping等注解需要升级 spring

  • 详解spring cloud使用Hystrix实现单个方法的fallback

    本文介绍了spring cloud-使用Hystrix实现单个方法的fallback,分享给大家,具体如下: 一.加入Hystrix依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 二.编写Controller package c

  • 详解spring cloud构建微服务架构的网关(API GateWay)

    前言 在我们前面的博客中讲到,当服务A需要调用服务B的时候,只需要从Eureka中获取B服务的注册实例,然后使用Feign来调用B的服务,使用Ribbon来实现负载均衡,但是,当我们同时向客户端暴漏多个服务的时候,客户端怎么调用我们暴漏的服务了,如果我们还想加入安全认证,权限控制,过滤器以及动态路由等特性了,那么就需要使用Zuul来实现API GateWay了,下面,我们先来看下Zuul怎么使用. 一.加入Zuul的依赖 <dependency> <groupId>org.spri

  • 详解Spring Cloud 跨服务数据聚合框架

    AG-Merge Spring Cloud 跨服务数据聚合框架 解决问题 解决Spring Cloud服务拆分后分页数据的属性或单个对象的属性拆分之痛, 支持对静态数据属性(数据字典).动态主键数据进行自动注入和转化, 其中聚合的静态数据会进行 一级混存 (guava). 举个栗子: 两个服务,A服务的某张表用到了B服务的某张表的值,我们在对A服务那张表查询的时候,把B服务某张表的值聚合在A服务的那次查询过程中 示例 具体示例代码可以看 ace-merge-demo 模块 |------- ac

  • 详解Spring Cloud Zuul网关修改为短连接方法

    目录 一.问题分析 二.解决方式 一.问题分析 之前在用zuul网关的时候,请求几次然后连接就断开了.原因是因为http1.1之后,默认走的都是connection=keep-alive 长连接.但没有心跳维持,顾1分钟断开一次.但RestFul一般都是走短连接就行了.因此想着只要修改头部connection属性就行了. 就是在过滤器中修改Zuul的RequestContext ctx对象 //设置请求为短连接 ctx.addZuulRequestHeader("connection"

  • 详解spring cloud config实现datasource的热部署

    关于spring cloud config的基本使用,前面的博客中已经说过了,如果不了解的话,请先看以前的博客 spring cloud config整合gitlab搭建分布式的配置中心 spring cloud config分布式配置中心的高可用 今天,我们的重点是如何实现数据源的热部署. 1.在客户端配置数据源 @RefreshScope @Configuration// 配置数据源 public class DataSourceConfigure { @Bean @RefreshScope

  • 详解spring cloud config整合gitlab搭建分布式的配置中心

    在前面的博客中,我们都是将配置文件放在各自的服务中,但是这样做有一个缺点,一旦配置修改了,那么我们就必须停机,然后修改配置文件后再进行上线,服务少的话,这样做还无可厚非,但是如果是成百上千的服务了,这个时候,就需要用到分布式的配置管理了.而spring cloud config正是用来解决这个问题而生的.下面就结合gitlab来实现分布式配置中心的搭建.spring cloud config配置中心由server端和client端组成, 前提:在gitlab中的工程下新建一个配置文件config

  • 详解Spring Cloud Feign 熔断配置的一些小坑

    1.在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,已解决. 2.使用feign默认配置,熔断不生效,已解决. 最近在做微服务的学习,发现在使用feign做服务调用时,使用继承的方式调用服务,加入Hystrix的熔断处理fallback配置时,会报错,代码如下: @RequestMapping("/demo/api") public interface HelloApi { @GetMapping("user/

  • 详解spring cloud中使用Ribbon实现客户端的软负载均衡

    开篇 本例是在springboot整合H2内存数据库,实现单元测试与数据库无关性和使用RestTemplate消费spring boot的Restful服务两个示例的基础上改造而来 在使用RestTemplate来消费spring boot的Restful服务示例中,我们提到,调用spring boot服务的时候,需要将服务的URL写死或者是写在配置文件中,但这两种方式,无论哪一种,一旦ip地址发生了变化,都需要改动程序,并重新部署服务,使用Ribbon的时候,可以有效的避免这个问题. 前言:

随机推荐