Spring Cloud

Spring Cloud

微服务产生背景

在这里插入图片描述
单体应用存在的问题:
!随着业务的发展,开发变得越来越复杂
!修改、新增某个功能,需要对整个系统进行测试,重新部署。
!一个模块出现问题,很有可能导致整个系统崩溃。
!多个团队同时对数据进行管理,容易产生安全漏洞;
!各个模块使用同一种技术框架,局限性太大,很难根据业务选择最适合的技术框架。
!模块的内容太复杂,如果有员工离职,可能需要很长时间才能完成任务的交接。
为了解决上述问题,微服务应运而生,简单来说,微服务就是将一个单体应用拆分成若干个小型服务,协同完成系统功能的一种框架模式,再系统框架层面进行解耦合,将一个复杂问题拆分成若干个简单问题。
这样的好处是对于每一个简单问题,开发、维护、部署的难度就降低了很多,可以实现自治,可以自主选择最适合的技术框架,提高了项目开发的灵活性。
微服务不仅是简单的拆分,拆分之后的微服务之间还要进行通信,否则就无法协同完成需求。
微服务之间只需要制定统一的协议即可,至于说每个微服务使用什么技术框架来完成,系统不需关心。这种松耦合的方式使得开发、部署都变得灵活,同时系统更容易扩展,降低了开发、运维的难度。
在这里插入图片描述

微服务的优点:

!各个微服务之间实现了松耦合,彼此之间不需要关注对方是用什么语言,什么技术,只需要报纸自己的接口可以正常访问即可,通过标准协议访问其他接口即可。
!各个微服务之间独立自治,只需要专注于做好自己的业务,开发和维护不会影响到其他的微服务。
!微服务是一种去中心化的构架方式,相当于用零件拼接一台机器,如果某个零件出现了问题,了可以随时进行替换,从而保证机器的正常允许。

微服务之间的不足

!如果某个系统的远程调用出现了问题,导致微服务不可用,就有可能产生级联反应,造成整个系统的崩溃。
!如果某个需求要调用多个微服务,如何保证数据的一致性。
!相比于单体应用,微服务的学习难度会增加,对于团队新加入的员工来讲,如何快速掌握并上手微服务架构,是一个问题。

微服务的设计原则

从大到下,提炼出核心需求,搞清楚服务间的交互关系,先拆分成粒度较大的服务,然后再根据具体的业务需求逐步细化服务粒度,最终形成一套合理的微服务系统架构。
!服务粒度不能太小也不能太大,提炼核心需求,根据服务间的交互关系找到合理的服务粒度。
!各个微服务的功能职责尽量单一,避免多个服务处理同一个需求。
!各个微服务之间要相互独立、自治,自主开发、自主测试、自主部署、自主维护。
!保证数据的独立性,各个微服务独立管理其业务模块下的数据。
!使用RESTful协议完成微服务之间的协作任务,数据交互采用JSON格式,方便调用和整合。
在这里插入图片描述

微服务架构的核心组件

!服务治理
@服务注册
@服务发现
提供服务的叫做服务提供者,调用服务的叫做服务消费者。
!服务的负载均衡
!服务网关
当用户端就比如访问淘宝时,用户要访问一个需要几个的微服务才能完成的功能时,如果没有服务网关,就需要访问很多的URL,但有服务网关之后,服务网关只提供一个地址,服务端只需要调用服务网关给的这个地址,然后由服务网关再去调用其他的微服务即可。
!微服务的容错机制
为了保护整个系统,如果哪儿出错,直接切断即可。
!分布式配置
对每一个服务的配置文件进行统一管理。
!服务监控
微服务之间会相互调用,服务监控是跟踪每个微服务调度的信息。

解决方法

Spring Cloud
微服务是一种分布式软件架构设计方式,具体的落地方案有很多,Dubbo、Spring Boot、Spring Cloud等等,spring Cloud是基于Spring Boot使得整体的开发、配置、部署都非常方便,可以快速搭建基于微服务的分布式应用,Spring Cloud相对与微服务各个组件的集大成者。

Spring Boot 和Spring Cloud的关系

Spring Boot可以快速的搭建基础系统,Spring Cloud在此基础上实现分布式系统中的公共组件,如服务注册、服务发现、服务管理、熔断器、控制总线等,服务器调用方式是基于REST APL。
在这里插入图片描述

搭建微服务核心中枢

服务治理的核心组件:
!服务提供者
!服务消费者
!注册中心
分布式系统架构中,每个微服务在启动时,将自己的信息存储在注册中心,服务注册。
服务的消费者从注册中心查询服务提供者的网络信息,并通过此信息调用服务提供者的接口,服务发现。
注册中心需要管理各个微服务:通过心跳机制,每隔一定的时间,微服务会向注册中心进行汇报,如果注册中心长时间无法与某个微服务通信,就会自动销毁该服务。
当某个微服务的网络信息发生变化时,也会重新注册。
服务提供者、服务消费者、注册中心的关联:
!启动注册中心
!服务提供者启动后,在注册中心注册一个提供服务的实例。
!服务消费者启动,在注册中心订阅需要调用的服务。
!注册中心将服务提供者的信息推送给服务调用者。
!服务调用者通过相关信息(IP、端口)调用服务提供者的服务。
注册中心核心模块:
!服务注册表
!服务注册
!服务发现
!服务检查
Spring Cloud的服务治理可以使用Eureka组件。

什么是Eureka?

Spring Cloud Erureka,提供服务注册和服务发现的两个功能。

Spring Cloud Eureka的组成

Euraeka Server服务端

Eureka Client客户端
在这里插入图片描述

代码实现

1、pom.xml,记住<artifactId>spring-boot-starter-parent</artifactId>的版本要改为2.3.0.RELEASE,

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wdzl</groupId>
    <artifactId>springcloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud Hoxton -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring Cloud Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

2、在父工程下的创建一个Module,实现Eureka,pom.xml中的<parent>里的东西改成你上一个一个模板的,并且最好在父工程添加<packaging>pom</packaging>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wdzl</groupId>
        <artifactId>springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wdzl</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

3、application.yml

spring:
  cloud:
    nacos:
      discovery:
        # 指定nacos server地址
        server-addr: localhost:8848
  application:
    name: my-nacos
server:
  port: 8383

第一个案例:
1、启动nacos
2、eureka中的controller:

    @GetMapping("/list")
    public List<User> list(){
        return Arrays.asList(
                new User(1,"曲波"),
                new User(2,"赵童"),
                new User(3,"唐某")
        );
    }

启动运行时类,输入添加链接描述后登录,名称时nacos,密码是nacos。
此时你会看到如下界面:
在这里插入图片描述
这里里面就是你的服务,注意你可以向nacos中添加多个服务,步骤:
1、
在这里插入图片描述

2、
在这里插入图片描述
这样操作之后就可以启动多个服务了;
简单的加入多个服务:
你只需要将你eureka中的配置文件修改不同之后,在启动运行类,就可以得到多个服务;
在这里插入图片描述

案例2

1、eureka.controller

    @GetMapping("/list")
    public List<User> list(){
        return Arrays.asList(
                new User(1,"曲波"),
                new User(2,"赵童"),
                new User(3,"唐某")
        );
    }

2、启动服务
3、consumer访问

    @GetMapping("/toProvider")
    public List<User> toProvider(){
        //随机调用一个provider服务
        List<ServiceInstance> list = this.discoveryClient.getInstances("my-nacos");
        //获取一个随机数,范围不能超过集合的下标
        int index = ThreadLocalRandom.current().nextInt(list.size());
        ServiceInstance serviceInstance = list.get(index);
        String url = serviceInstance.getUri() + "/list";
        //调用url,
        List object = this.restTemplate.getForObject(url, List.class);
        return object;
    }

4、启动

负载均衡演示案例

eureka:

@RestController
public class UserController {
    //读取配置文件
    @Value("${server.port}")
    private String port;
    
    @GetMapping("/index")
    public String index(){
        return "你现在调用的是my-nacos服务,"+port;

    }
}

consumer:

    @GetMapping("/nihao")
    public String index(){
        String result= "Consumer通过RestTemplate,调用结果:";
        //调用my-nacos
        List<ServiceInstance> list = this.discoveryClient.getInstances("my-nacos");
        //随机选一个
        int index = ThreadLocalRandom.current().nextInt(list.size());
        ServiceInstance serviceInstance = list.get(index);
        //拼接URL
        String url = serviceInstance.getUri() + "/index";
        //通过RestTemplate完成调用
        String forObject = this.restTemplate.getForObject(url, String.class);
        return result+ forObject;
    }

Ribbon 负载均衡案例简化

1、RestTemplate 添加@LoadBalanced注解
代码:

@Configuration
public class RestTemplateConfiguration {
@Bean
@LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

controller:

    @GetMapping("hello")
    public String index1(){
       
        String result= "Consumer通过RestTemplate,调用结果:";
        return result+this.restTemplate.getForObject("http://my-nacos/index",String.class);
    }

这就相对与访问的这个地址,是在nacos中去找一个服务名叫做:my-nacos的服务,然后随机取一个,这个随机默认是轮询的方式;

随机方式:
consumer中的yml

server:
  port: 8888
my-nacos:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

基于nacos权重的方式:
1、创建 NacosWeightedRule 类定义基于权重的负载均衡

package com.wdzl.configuration;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        //读取配置文件
    }

    @Override
    public Server choose(Object o) {
        ILoadBalancer loadBalancer = this.getLoadBalancer();
        BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) loadBalancer;
        //获取要请求的微服务名称
        String name = baseLoadBalancer.getName();
        //获取服务发现的相关API
        NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
        try {
            Instance instance = namingService.selectOneHealthyInstance(name);
            log.info("选择的实例是port={},instance={}",instance.getPort(),instance);
            return new NacosServer(instance);
        } catch (NacosException e) {
            e.printStackTrace();
            return null;
        }
    }
}

2、修改配置文件负载均衡规则为 NacosWeightedRule

server:
  port: 8888
my-nacos:
  ribbon:
    NFLoadBalancerRuleClassName: com.southwind.configuration.NacosWeightedRule

在这里插入图片描述
需要这样修改之后才能看到结果;

Fiegen 声明式接口调用

什么是Feign
Netfilx,Feign是一个提供模板的声明式Web Service客户端,使用Feifn可以简化Web Service客户端的编写,开发者可以通过简单的接口和注解来调用HTTP API。
Spring Cloud Fegin :可插拔(耦合性比较低)、基于注解、负载均衡、服务熔断;
只需要创建接口,同时在接口上添加相关注解即可。
Ribbon和Fiegen的区别:
!Ribbon是一个通用的HHTTP客户端工具,Feign是基于Ribbon,更加灵活;
Feign的特点:
!Feign是一个声明式的web Service客户端
!支持Fegin注解、Spring MVC注解
!Feign基于Ribbon实现
!Feign集成了Hystrix
1、创建Modul,pom.xml中添加相关依赖

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、创建Feiggn接口

@FeignClient("my-nacos")//你的服务名字
public interface Feign {
    @GetMapping("/index")
    public String index();//你要访问的方法名
}

3、启动类添加注解

@SpringBootApplication
@EnableFeignClients
public class ConsumerApplication {

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

}

4、controller

@GetMapping("/index")
    public String index2(){
        return "consumer远程调用provier:"+this.feign.index();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值