SpringCloud入门知识

1. 微服务
1.1 架构体系演变过程

在这里插入图片描述
单体架构: 就是将所有的业务场景的表示层、业务逻辑层和数据,访问层放在一个工程中,最终经过编译、打包,部署在一台服务器上。。

垂直架构: 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率.

分布式架构: 表示把不同的层进行分开来管理,其实就是可以按照mvc架构,只不过把每个层变成一个单独的服务

SOA架构: 基于分布式架构的基础之上进行细粒化拆分的一种架构.
面向服务架构,其实就是把每个项目拆分成多个独立的服务,而每个服务中都一个独立的个体.

小结:
​ 分布式架构和SOA架构目前比较流程的技术栈还是ssm或者ssh.

微服务架构:
​ 微服务架构是一项在云中部署应用和服务的新技术,微服务可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通.

简单来说:微服务,是在soa架构的基础之上进行再次的细粒化,达到“微”的程度,每个服务都是一个独立的个体服务,服务与服务之间耦合性比较小,而且微服务架构使用的技术栈必须是springboot为底层的技术栈,比如springcloud.

2. springcloud

概念:
​ springcloud是spring家族的一个产品,springcloud不是一个具体的技术,而是多个组件的集合,包含的组件常用的有:
eureka,fegin,ribbon,alibaba,gateway,bus,config等等.

springcloud版本号是以英国伦敦地铁站的名称来命名的。
springcloud和dubbo的对比分析
在这里插入图片描述

3. SpringCloud服务治理
3.1 Eureka的了解

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行

3.2 Eureka入门操作
3.2.1 不使用Eureka来完成服务之间的调用

思路:

  1. 创建一个provider服务,专门用来从数据库获取数据
  2. 创建一个consumer服务,去调用provider服务

provider服务部分:
1 导入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

2 创建实体

@Data
@AllArgsConstructor
public class Goods {

    private int id;
    private String title;//商品标题
    private double price;//商品价格
    private int count;//商品库存
}

3 编写dao

@Repository//注入到ioc容器
public class GoodsDao {
    //单一查
    public Goods findOne(int id){
        return new Goods(1,"华为手机",3999,10000);
    }
}

4 编写controller

@RestController
@RequestMapping("/provider")
public class ProviderController {

    @Autowired
    private GoodsDao goodsDao;

    @GetMapping("/findOne/{id}")
    public Goods findOne(@PathVariable Integer id){
       return goodsDao.findOne(id);
    }
}

5 启动入口类,访问服务 localhost:9091/provider/findOne/12

Consumer服务部分:
1 导包

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

2 实体类

@Data  //lombok插件  提供setXxx,getXxx
@AllArgsConstructor  //满参构造
@NoArgsConstructor   //空参构造
public class Goods {

    private int id;
    private String title;//商品标题
    private double price;//商品价格
    private int count;//商品库存
}

3 编写RestTemplateConfig

@Configuration
public class RestTemplateConfig {

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

4 编写controller

/*
要去调用provider服务
 */
@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    //根据商品id调用商品信息
    @GetMapping("/findGoodsById/{id}")
    public Goods findGoodsById(@PathVariable int id){
        System.out.println("findGoodsById..."+id);
        //1.调用provider服务中的接口
        String url="http://localhost:9091/provider/findOne/"+id;
        //2.利用restTemplate模板模拟浏览器发请求
        Goods goods = restTemplate.getForObject(url, Goods.class);
        return goods;
    }
}

5 测试访问consumer服务 localhost:9090/consumer/findGoodsById/12

总结:
​ RestTemplate是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果,而且是比较优雅的http请求方式.

简单来说就是模拟了浏览器发出请求的方式。

3.2.2 使用Eureka来完成服务之间的调用

使用eureka的服务
1 导包,在parent工程中加入依赖

	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <!--spring cloud 版本-->
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

    <!--引入Spring Cloud 依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2 在eureka-server服务中加入依赖

 <dependencies>

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

        <!-- eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

3 在入口类之上加入开启Eureka服务的注解

@SpringBootApplication
//加入开启euerka服务的注解
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

4 配置文件yml

server:
  port: 8080

eureka:
  instance: #实例
    hostname: localhost # 主机名
  client:
    service-url:
        #   http://localhost:8080/eureka  这个地址是eureka服务端和客户端之间通信的接口地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    #注册
    register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    #发现
    fetch-registry: false  # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

spring:
  application:
    name: eureka_server

5 启动Eureka-server服务,localhost:8080

使用Eureka完善服务之间的调用
主要核心把provider和consumer这两个服务变成Eureka client服务

一 provider服务提供者部分
1 pom.xml导包

  <!-- eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2 在入口类之上可以加@EnableEurekaClient注解,新版springcloud也可以选择不加.

3 在配置文件配置关联EurekaServer信息.

eureka:
    instance:
      hostname: localhost # 主机名
    client:
      service-url:
        defaultZone: http://localhost:8080/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

  #如果不进行指定服务名称,则会显示unknown
spring:
    application:
      name: cloud-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

二 consumer服务消费者部分
1.pom.xml导包

  <!-- eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2 在入口类之上可以加@EnableEurekaClient注解,新版springcloud也可以选择不加

3 在配置文件配置关联EurekaServer信息

eureka:
    instance:
      hostname: localhost # 主机名
    client:
      service-url:
        defaultZone: http://localhost:8080/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

  #如果不进行指定服务名称,则会显示unknown
spring:
    application:
      name: cloud-consumer # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

三 服务消费者consumer远程调用服务生产者provider
在consumerController类中改造代码

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    //根据商品id调用商品信息
    @GetMapping("/findGoodsById/{id}")
    public Goods findGoodsById(@PathVariable int id){
        System.out.println("findGoodsById..."+id);
        //1.调用provider服务中的接口
       /* String url="http://localhost:9091/provider/findOne/"+id;
        Goods goods = restTemplate.getForObject(url, Goods.class);*/
        //从eureka 服务列表中获取客户端服务列表,参数表示的是服务id
        List<ServiceInstance> instanceList = discoveryClient.getInstances("CLOUD-PROVIDER1");
        ServiceInstance serviceInstance = instanceList.get(0);

        int port = serviceInstance.getPort();
        String host = serviceInstance.getHost();
        String instanceId = serviceInstance.getInstanceId();
        System.out.println("port=|"+port+"| host=|"+host+"|  instanceId=|"+instanceId);


        String url="http://"+host+":"+port+"/provider/findOne/"+id;
        Goods goods = restTemplate.getForObject(url, Goods.class);
        return goods;
    }
}

小结:
当我们的生产者服务要先注册到Eureka Server中,然后消费者服务才可以去Eureka Server中去 发现生产者服务.
Eureka两个功能:
1 第一个是注册中心
2 第二是远程调用

四 对Eureka配置进行操作
instance属性,写在client客户端服务中,控制的是Eureka服务列表中的服务.

eureka:
    instance:
      hostname: localhost # 主机名
      prefer-ip-address: true
      ip-address: 127.0.0.1
      instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port}
    client:
      service-url:
        defaultZone: http://localhost:8080/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

server属性,写在Eureka server服务中,控制的是Eureka注册中心的自我保护机制.

  #表示Eureka自我保护机制
  server:
    enable-self-preservation: false  #默认是true表示开启,false表示关闭
    eviction-interval-timer-in-ms: 60000
3.2.3 Eureka集群高可用

在这里插入图片描述
实现步骤:

  1. 准备两个Eureka Server
  2. 分别进行配置,相互注册
  3. Eureka Client 分别注册到这两个 Eureka Server中

操作步骤:
1、导包

2、在入口类之上加入开启Eureka服务的注解@EnableEurekaServer

3、配置文件

eureka-server1模块中:

eureka:
  instance: #实例
    hostname: 127.0.0.1 # 主机名
  client:
    service-url:
        #   http://localhost:8080/eureka  这个地址是eureka服务端和客户端之间通信的接口地址
      defaultZone: http://127.0.0.2:10080/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    #注册
    register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    #发现
    fetch-registry: true  # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

eureka-server模块中:

eureka:
  instance: #实例
    hostname: 127.0.0.2 # 主机名
  client:
    service-url:
        #   http://localhost:8080/eureka  这个地址是eureka服务端和客户端之间通信的接口地址
      defaultZone: http://127.0.0.1:8080/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信
    #注册
    register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要
    #发现
    fetch-registry: true  # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

生产者服务和消费者服务中注册或者发现两台Eureka-server

eureka:
  instance:
    hostname: 127.0.0.1 # 主机名
  client:
    service-url:
      defaultZone: http://127.0.0.1:8080/eureka,http://127.0.0.2:10080/eureka 
      # eureka服务端地址,将来客户端使用该地址和eureka进行通信  
      以逗号间隔,
3.2 Consul
3.2.1 Consul的概述

Consul 是由 HashiCorp 基于 Go 语言开发的,支持多数据中心,分布式高可用的服务发布和注册服务软件。

• 用于实现分布式系统的服务发现与配置。
• 使用起来也较 为简单。具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署 。

consul官网地址

启动命令: .\consul agent -dev
(dev模式:不会持久化数据)

3.2.2 Consul的入门案例

consul工作结构图
实现步骤:

  1. 搭建 Provider 和 Consumer 服务。
  2. 使用 RestTemplate 完成远程调用。
  3. 将Provider服务注册到Consul中。
  4. Consumer服务通过从 Consul 中抓取 Provider 地址完成远程调用。

一. Provider模块

  1. pom.xml
<dependencies>

        <!--consul 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

        <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>

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

    </dependencies>
  1. 配置文件application.yml
server:
  port: 8000
spring:
  cloud:
    consul:
      host: localhost # consul 服务端的 ip
      port: 8500 # consul 服务端的端口 默认8500
      discovery:
        service-name: ${spring.application.name} # 当前应用注册到consul的名称
        prefer-ip-address: true # 注册ip

  application:
    name: consul-provider # 应用名称

二. Consumer模块
1-pom.xml

<dependencies>
        <!--consul 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <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>

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

    </dependencies>

2-配置文件application.yml

server:
  port: 9000


spring:
  cloud:
    consul:
      host: localhost # consul 服务端的 ip
      port: 8500 # consul 服务端的端口 默认8500
      discovery:
        service-name: ${spring.application.name} # 当前应用注册到consul的名称
        prefer-ip-address: true # 注册ip

  application:
    name: consul-consumer # 应用名称

3-Consumer控制层Controller

package com.cf.consul.controller;

import com.cf.consul.domain.Goods;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * 服务的调用方
 */

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){
        //演示discoveryClient 使用
        List<ServiceInstance> instances = discoveryClient.getInstances("consul-PROVIDER");

        //判断集合是否有数据
        if(instances == null || instances.size() == 0){
            //集合没有数据
            return null;
        }

        ServiceInstance instance = instances.get(0);
        String host = instance.getHost();//获取ip
        int port = instance.getPort();//获取端口

        System.out.println(host);
        System.out.println(port);

        String url = "http://"+host+":"+port+"/goods/findOne/"+id;
        // 3. 调用方法
        Goods goods = restTemplate.getForObject(url, Goods.class);

        return goods;
    }
}

三. 测试
http://localhost:8500

3.3 Nacos
3.3.1 Nacos的概述

Nacos(Dynamic Naming and Configuration Service) 是阿里巴巴2018年7月开源的项目。
• 它专注于服务发现和配置管理领域 致力于帮助您发现、配置和管理微服务。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理。

• 一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。

Nacos官网地址

使用步骤:
双击startup.cmd或通过命令行方式 start “xx.cmd”
控制台账号,密码默认为:nacos

3.3.2 Nacos的入门案例

一. nacos-provider提供者模块
1-pom.xml

<dependencies>

        <!--nacos-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.1.0</version>
        </dependency>


        <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>

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

    </dependencies>

2-application.yml

server:
  port: 8000
spring:
  cloud:
    nacos:
      discovery:
        server-addr:  127.0.0.1:8848 # 配置nacos 服务端地址
  application:
    name: nacos-provider # 服务名称

二. nacos consumer消费者模块

<dependencies>

        <!--nacos-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.1.0</version>
        </dependency>


        <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>

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

    </dependencies>

2-application.yml

server:
  port: 9000

spring:
  cloud:
    nacos:
      discovery:
        server-addr:  127.0.0.1:8848 # 配置nacos 服务端地址
  application:
    name: nacos-consumer # 服务名称

三. 测试 http:localhost:8848/nacos

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值