springCloud-学习笔记

单词

discoveryClient-发现客户端、loadBalance-负载均衡、Rule-规则、current-当前的、fallback-回退(降级)、break-中断(熔断)、flowlimit-限流、circuit-电路、dashboard-仪表盘、refresh-刷新、actuator-执行器

SpringCloud是一系列框架的有序集合,是一揽子框架的解决方案

约定 > 配置 > 编码

微服务架构

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建

分布式架构

或者说是对分布式架构的理解

  • 服务注册与发现
  • 服务调用
  • 服务熔断
  • 负载均衡
  • 服务降级
  • 服务消息队列
  • 配置中心管理
  • 服务网关
  • 服务监控
  • 全链路追踪
  • 自动化构建部署
  • 服务定时任务调度操作

一些架构需要学习掌握的技术

image-20210915215045613

开始搭建项目

  • dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
  <!--dependencyManagement: 子模块继承之后,提供作用:锁定版本+子module不用写groupId和version  -->
	<dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            ......

这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改﹔另外如果某个子项目需要另外的一个版本,只需要声明version就可。

跳过maven的test单元测试,项目可以跑的更快

image-20210916202236605

一个微服务模块搭建的基本流程

1、建module

2、改POM

3、写YML

4、主启动

5、业务类

RestTemplate

RestTemplate提供了多种便捷访问远程Http服务的方法,
是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集

1、创建一个父类总工程

pom.xml

<dependencyManagement>: 子模块继承之后,提供作用:锁定版本+子module不用写groupId和version
    </dependencyManagement>

2、编写服务的生产者

1、建module

​ cloud_provider_payment8001

2、改POM


需要的依赖
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<artifactId>druid-spring-boot-starter</artifactId>
<artifactId>mysql-connector-java</artifactId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<artifactId>spring-boot-devtools</artifactId>
<artifactId>lombok</artifactId>
<artifactId>spring-boot-starter-test</artifactId>

3、写YML

改端口号8001,mysql jdbc 驱动 数据源 ,mybatis扫描

4、主启动

编写主启动类

5、业务类

​ 5.1、编写Payment.java 的bean

​ 5.2、编写CommontResult.java 的bean 面相前端开放的一个bean,前端只需要调用这个bean的结果即可

​ 5.3、Dao、DaoImpl、mapper.xml

​ 5.4、service、serviceImpl

​ 5.5、controller

​ 消费者调用该写入数据库的业务时,会给生产者传回一个json字符串,造成写入数据库错误,写入一个null值,所以需要在形参中加上==@RequestBody== 注解 将传回来的字符串转换成对象

@Autowired
    private PaymentService paymentService;

    @PostMapping(value="/payment/create")
    public CommonResult create(@RequestBody Payment payment){
   
        int result = paymentService.create(payment);
        log.info("=====插入结果====="+payment);
        if(result > 0){
   
            return new CommonResult(200,"插入成功",payment);
        }
        return new CommonResult(444,"插入失败",payment);
    }

3、编写服务的消费者

1、建module

​ cloud_consumer_order80

2、改POM

<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-devtools</artifactId>
<artifactId>lombok</artifactId>
<artifactId>spring-boot-starter-test</artifactId>

3、写YML

​ 改端口号80 默认不用写就是80端口,所以消费者只用写ip地址即可访问服务

4、主启动

​ 主启动类

5、业务类

​ 5.1、编写Payment.java 的bean

​ 5.2、 编写CommonResult.java 的 bean

​ 5.3 编写config配置类 ApplicationContextConfig.java

// 配置类
@Configuration
public class ApplicationContextConfig {
   
    // 可以复用的restTemplate方法
    @Bean
    public RestTemplate getRestTemplate(){
   
        return new RestTemplate();
    }
}

​ 5.4、编写controller层

​ 使用到了RestTemplate , 写操作使用postForObject() , 读操作使用getForObject()

@RestController
@Slf4j
public class OrderController {
   
    @Resource
    private RestTemplate restTemplate;
    public static final String PAYMENT_URL = "http://localhost:8001";
    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment) {
   
        // 用于访问Rest服务的客户端模板工具集  ( URL访问地址,传参类型,返回类型 )
        return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
    }

    @GetMapping("/consumer/payment/getPayment/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") long id){
   
        return restTemplate.getForObject(PAYMENT_URL+"/payment/getPayment/"+id,CommonResult.class);
    }
}

创建一个抽取公用API的模块

1、pom.xml

新加入了一个hutool工具包
<artifactId>hutool-all</artifactId>

2、将entities实体类包抽取出来

3、使用maven的生命周期的方法

​ 3.1、clean清空

​ 3.2、install安装打包一下

4、在需要使用到该实体类的模块中引入依赖

<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.study</groupId>
            <artifactId>cloud_api_commons</artifactId>
            <version>${project.version}</version>
</dependency>

Eureka

( 已停止更新 )

Eureka包含两个组件 : Eureka ServerEureka Client

Eureka Server提供服务注册服务

​ 各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有 可用服务节点的信息,服务节点的信息可以在界面中直观看到。

EurekaClient通过注册中心进行访问

​ 是一个lava客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round- robin)负载算 法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如 果Eureka Server在多个心 跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这 个服务节点移除(默认90秒)

服务注册中心

需要先启动服务注册中心,再服务的提供者。

创建服务注册中心模块

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

服务注册中心的yaml

server:
  port: 7001

eureka:
  instance:
    hostname: localhost # eureka服务端的实例名称
  client:
    #false表示不向注册中心注册自己
    register-with-eureka: false
    #false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${
   eureka.instance.hostname}:${
   server.port}/eureka/

服务注册中心的主启动类

@SpringBootApplication
@EnableEurekaServer // 表示自己是Eureka服务注册中心
public class EurekaMain7001 {
   ...}

服务提供者

依赖

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

服务提供者的yaml

eureka:
  client:
    #表示是否将自己注册进EurekaServer 默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      # 向哪个注册中心注册服务
      defaultZone: http://localhost:7001/eureka

服务提供者的主启动类

@SpringBootApplication
@EnableEurekaClient // 服务提供者,让注册中心发现、并扫描到该服务
public class PaymentMainAPP {
   ...}

集群版Eureka

1、新建一个服务的注册中心 eureka7002

2、在windows的hosts文件中加上本机的ip地址,服务注册中心的服务名( 相当于域名 )

127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com

3、修改服务注册中心的yaml文件

​ 3.1、修改eureka服务名 eureka7001.com 在浏览器地址栏中输入,可以映射到127.0.0.1

127.0.01 localhost 192.168.177.1(127.0.0.1 = 本机ip地址 ,localhost = 本机的域名,192.168.177.1 = 本机网卡对外的ip))

​ 3.2、修改 defaultZone :ip地址:port/eureka/

​ ,之前是单机版本,只需要把自己的地址注册上即可,现在是集群,所以要写上其他服务注册中心的地址

​ 多台服务注册中心需要 相互注册互相关联相互守望 , 如果有多台可以用 ==,==逗号隔开

server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com # eureka服务端的实例名称
  client:
    #false表示不向注册中心注册自己
    register-with-eureka: false
    #false 表示自己段就是注册中心,我的职责就是我维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
#      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      #使用集群的方式
      defaultZone: http://eureka7002.com:7002/eureka/

Client向集群注册中心注册服务

修改yaml文件

eureka:
  client:
    #表示是否将自己注册进EurekaServer 默认为true
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      # 向哪个注册中心注册服务
#      defaultZone: http://localhost:7001/eureka
      #向集群注册中心注册服务
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

Client端集群(提供者)

不仅要做服务注册中心的集群,还要做服务提供者的集群,这样可用性更高

1、再创建一个服务提供者的模块 cloud_provider_payment8002

​ 1.1、改 POM

​ 1.2、写YAML

​ yaml的端口号改成8002,(多个服务提供者的服务名需要保持一致,让消费者可以通过一个服务名找到多个提供者)

​ 1.3 、主启动类

​ 1.4、业务类

​ 可选: 可以在controller层加上 以便以端口号识别的参数

@Value("${server.port}") // 从配置文件中读取端口号
private String serverPort ;
....
    return new CommonResult(200,"查询成功 + " + serverPort,paymentById);

2、在消费者 (80端口)修改controller层的URL访问地址

//    public static final String PAYMENT_URL = "http://localhost:8001";
// URL访问地址从服务提供者的ip改成服务提供者集群对外暴露的服务名(需要在RestTemplate的配置上加上@LoadBalanced 在可以生效)
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT";

​ 2.1、给RestTemplate加上注解@LoadBalance 赋予它负载均衡的能力 (默认轮询的方式来负载均衡)

// 配置类
@Configuration
public class ApplicationContextConfig {
   
    // 可以复用的restTemplate方法
    @Bean
    @LoadBalanced // 赋予RestTemplate 负载均衡的能力
    public RestTemplate getRestTemplate(){
   
        return new RestTemplate();}}

完善微服务的配置信息(可选)

前台监控页面查看时可以显示更详细的信息
instance:
  instance-id: payment8001 #显示服务的主机名
  prefer-ip-address: true  #访问路径可以显示服务的ip地址

服务发现Discover

使用参数DisCoverClient

@Resource//DiscoverClient服务发现
private DiscoveryClient discoveryClient;

写方法获取实例信息

@GetMapping(value = "/payment/discover")
public Object discover(){
   
    // Eureka注册的微服务有哪些,服务列表清单
    List<String> services = discoveryClient.getServices();
    for (String element:services) {
   
        log.info("services--->"+element);
    }
    ------------------结果-----------------------------
        services--->cloud-order-com.study.cloud.service
		services--->cloud-payment-service
    ------------------------------------------------
    //根据微服务的名称,获取微服务具体的信息
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    for (ServiceInstance instance : instances) {
   
        // 可以使用根据服务名实例获取到的内容来get该服务名的详细的信息
        log.info("instance--->"+instance.getInstanceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
    }
    return this.discoveryClient;
}
--
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值