SpringCloud 基础

 

SpringCloud是一个微服务框架,用于搭建分布式应用。

SpringCloud是在SpringBoot的基础上,集成了多种技术,是一系列技术的集合,为微服务提供了一站式解决方案。

因为是建立在SpringBoot的基础上,所以具有SpringBoot的所有特点。

 

 

SpringCloud的特点:

  • 约定优于配置
  • 开箱即用
  • 部署环境多样,可以部署到PC Server、Docker、云端。
  • 组件轻量级,功能全面
  • 选型中立,并不是一定要用自带的组件,因为有spring强大的整合能力,也可以使用其它组件,比如服务发现不一定要用自带的Eureka,也可以用Zookeeper,但SpringCloud对Eureka的支持最好。 

 

 

SpringCloud的技术栈 | 组件 | 全家桶:

  • Spring Cloud Eureka  服务治理
  • Spring Cloud Ribbon  负载均衡
  • Spring Cloud Hystrix  断路保护
  • Spring Cloud Zuul  网关(API Gateway)
  • Spring Cloud Config、Bus、Sleuth   (可选)

SpringCloud的组件都是轻量级的。

前4个对于SpringCloud微服务都是必需的,第5项列出的是可选的,根据需求选择。

Eureka、Ribbon、Hystrix都是netflix的开源项目,SpringCloud都将它们集成了。

 

 

SpringCloud的版本

SpringCloud 基础_第1张图片

其它框架的版本都是1.x,2.x这样命名走的,SpringCloud的版本是Axx、Bxx、Cxx这样命名走的。

ga是稳定版;snapshot是正在开发的版本,不稳定。

 

 


 

 

服务调用的demo

比如要查询某用户的所有订单 => 在用户服务中访问订单服务。

 

订单服务

@Controller
@RequestMapping("/order")
public class OrderController {
    //根据user_id查询某用户的所有订单
    @GetMapping("/user/{user_id}")
    @ResponseBody
    public List queryOrdersByUserId(@PathVariable Integer user_id){
        //进过一系列操作,返回订单列表
        //.....
        return orderList;
    }

    //.....
}

方法返回值要返回给用户服务,需要@ResponseBody转换为json格式,不能String、List、Map、视图什么的直接传过去。

 

被调者本身可能要调用视图来显示,或者直接返回某种类型的数据,不返回json格式的数据,那被调者需要重新写一个方法来作为服务接口,返回json格式,供其他服务调用。

就算双方都要使用视图来响应浏览器,也不能在2个服务之间直接传递页面,可以把被调者的视图(模板引擎什么的)copy过来,让被调者以json格式返回视图名。

 

 

 

用户服务

@Controller
@RequestMapping("/user")
public class UserController {
    //springboot的服务之间使用REST相互访问、调用,springboot已经把REST封装为RestTemplate类,注入使用即可
    private RestTemplate restTemplate;

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/{user_id}/order")
    @ResponseBody
    public List queryOrdersByUserId(@PathVariable Integer user_id){
        //订单服务的地址
        String url = "http://localhost:8080/order/user/{user_id}";
        //参数:服务地址、期待返回的数据类型(class对象)、要传入的参数
        List orderList = restTemplate.getForObject(url, List.class,user_id);
        return orderList;
    }

    //.....

}

 

restTemplate.getForObject(url, targetClass,Object...args);     //参数可变

 

参数指的是url中的参数,比如:

String url = "http://localhost:8080/springboot/user/{group}/{user_id}";

restTemplate.getForObject(url, targetClass,实参1,实参2)    //第n个实参对应url中的第n个{ }

 

 

我们看到IDEA提示:不能自动装配,因为找不打RestTemplate类型的实例。

我们需要手动创建一个RestTempalte的实例:

@SpringBootApplication
public class App{
    // 通过指定的方法,自动创建Bean(RestTempalte)的一个实例,放到spring容器中
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class);
    }

}

在引导类中创建,可供此服务的所有类使用。

 

 


 

 

上面把服务的url写死在代码中,当然也可以写在application.yml中,使用@Value注入:

server:
  user:
    url: http://localhost:8080/springboot/order/user/{user_id}
    @Value("${server.user.url}")
    private String url;

 

虽然好修改url一些,但节点地址依然是死的、固定的,只会访问指定的节点,做负载均衡、或者服务节点增减时怎么办?

 

 


 

 

传统的方式是使用nginx做代理、负载均衡,由nginx决定分发到该服务的哪个节点。

可服务之间有大量的调用关系,总不能在有调用关系的2个服务之间都加上nginx吧:

SpringCloud 基础_第2张图片

访问量大的时候,比如购物网站 =>xx狂欢节,需要加服务节点,之后要把加的节点撤下来,这都要修改nginx上的节点信息,很麻烦。

 

 


 

 

微服务使用服务治理组件:

SpringCloud 基础_第3张图片

服务治理组件有2个功能:服务注册、服务发现。

SpringCloud使用Eureka来做服务治理组件,如果服务节点很多,也需要做Eureka的集群。

 

服务注册:

服务的各节点将节点信息(提供的服务、本机地址)注册到Eureka上,并通过心跳实时更新本节点的信息。

所谓心跳,是指节点每几十秒就向服务发现组件发送一段消息,像心跳一样稳定、有规律,表示该节点还在工作(活着);如果一个节点连续几次都没发送心跳,心不跳了,说明这个节点挂了,Eureka会自动删除该节点的信息。

 

服务发现:

可查询Eureka来获取(发现)提供该服务的所有节点的信息。

 

 


 

 

Eureka只是登记好服务节点的信息,并不知道要调用哪个节点来处理,还需要使用Ribbon来做负载均衡

SpringCloud 基础_第4张图片

比如服务A的a1节点要调用服务C:

(1)a1节点向Ribbon发送负载均衡请求

(2)Ribbon查询Eureka,拿到提供服务C的所有节点的信息表,根据指定的算法(比如轮询、加权轮询、随机等)来确定要使用c1节点

(3)Ribbon将c1节点的信息(ip)返回给a1节点

(4)a1节点根据ip向c1节点发起请求,调用服务C

 

 


 

 

feign

feign用于向服务提供者传递大量参数,自带Ribbon负载均衡的功能。

 

 


 

 

微服务容错

1、雪崩效应

服务往往存在嵌套调用,比如服务A调用服务B,服务B要调用服务C:

服务A -> 服务B -> 服务C

如果C出现什么问题,B一直阻塞着等C搞好;A一直阻塞着等B搞好,即雪崩效应。

请求越积越多,负载越来越大,,最终导致服务A、B、C都不可用。

 

 

2、容错

容错:当依赖出现问题时,对系统的影响程度,影响大——容错低,影响小——容错高。

 

提升微服务容错有3种方式:

  • 增加节点数量

这是通用的。

 

  • 为请求设置超时

多少秒内没有完成,就直接返回出错提示,这个请求就算处理完了,开始处理下一个请求。

 

  • 设置断路器

对某个服务的请求,一段时间内,失败个数达到指定值或者失败率达到指定值,就会熔断链路,返回我们自定义的数据(比如错误提示、空值等)。

熔断只是半熔断,断路器是半开状态,会放行一小部分对此服务的请求进行检测,如果请求成功率达到指定值,就认为此服务已被修复,会重新打开链路。

 

你可能感兴趣的:(SpringCloud 基础)