Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

SpringCloud笔记

2021/12/30 开发笔记
Word count: 1,907 | Reading time: 8min

笔记内容大多来自:尚硅谷SpringCloud框架开发教程

跟做笔记:https://blog.csdn.net/MOKEXFDGH/article/details/107209899

跟做工程代码: https://github.com/liusCoding/springcloud-2020、https://gitee.com/exclusiver/springcloud2020

MVN配置

  • 每个module的pom配置文件中最重要的三个:GAV即 groupIdartifactIdversion

  • dependencyManagement声明依赖的版本,可以起到作用:

      1. 约定依赖的统一版本
      2. 子module不用写groupId和version

      注:dependencyManagement只是声明了依赖的约定,但是在子模块中确定要使用这个依赖时,还是需要dependency指出,即dependencyManagement只是声明,并没有实际引入。此外,如果子模块想要摆脱约定版本的话,可以通过特别列出version从而指定版本

业务开发流程

  1. 建表SQL
  2. Entities
  3. Dao
  4. Service
  5. Controller

创建mysql数据库:

  1. 通过图形界面——字符集选 utf8, 排序规则选 utf8_general_ci
  2. 通过SQL
1
2
CREATE DATABASE  `wordpress` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE DATABASE `wordpress` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

请求模拟

  • 浏览器对POST支持不太友好,需要使用如PostMan等工具:浏览器输入http://localhost:8001/create?serial=23,一旦戴上了这个?xxx=yyy的请求参数,则会被认为是Get请求

注解使用

  • @mapper对应@Resource(javax.annotation)
  • @Repository对应@Autowired

在Dao层定义时,推荐使用@Mapper(apache.ibatis),而不是@Repository(org.springframework.stereotype),因为后者在插入的时候可能会有问题

添加热部署

  1. 添加devtools依赖到工程

    1
    2
    3
    4
    5
    6
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
    </dependency>
  2. 在pom中指定添加插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <fork>true</fork>
    <addResources>true</addResources>
    </configuration>
    </plugin>
    </plugins>
    </build>
  3. enabling automatic build

    热部署设置

  4. 修改"Updating Registrer" (通过在pom文件中ctrl+shift+alt+/按出maintenance)==>IDEA2021中不需要设置了

  5. 重启IDEA

注:上述只是重启,Jrebel才是真正意义上的热部署

RestTemplate

Java中调用第三方的接口API时,是通过HttpClient库来创建请求的;而对于通过基于Http的Restful微服务接口,Springboot提供了一套方法: RestTemplate

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class OrderController {

public static final String PAYMENT_URL = "http://localhost:8001";

@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
}
// ..
}

// 由于postForObject会以 application/json的形式发送数据, 所以在Payment系统的接口中如果不加上 @RequestBody 的话,则无法封装成相应的对象
public class PaymentController {
@Resource
private PaymentService paymentService;

@PostMapping(value = "/create")
public CommonResult<Payment> create(@RequestBody Payment payment) { // 加上@RequestBody注解
int result = paymentService.create(payment);
// ...
}

注册中心

  • 服务注册:将服务信息注册进注册中心
  • 服务发现:从注册中心上获取服务信息实质:存key服务命取value调用地址

eureka环境搭建

服务端server

  1. 创建相应的工程或者module
1
2
3
4
5
6
7
8
9
10

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

</dependencies>
  1. 编写yml
1
2
3
4
5
6
7
8
9
10
11
12
13
server:
port: 7001

eureka:
instance:
hostname: localhost
client:
# 表示不向注册中心注册自己
register-with-eureka: false
# 自己就是注册中心,职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  1. 给application加上EnableEurekaServer自动注入的注解,并表明是eureka服务端
1
2
3
4
5
6
7
8
9
10
11
12
13

/**
* @author MrLi
* @description
* @create 2021-12-30 16:46
**/
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}

客户端client

虽然叫客户端,但其实是相对于eureka服务而言的,对于暴露的rpc服务来看,他是接口服务的服务端

  1. 加pom

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-eureka-client</artifactId>
    </dependency>
  2. 增加yml配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    eureka:
    client:
    # 表示不向注册中心注册自己, 默认为true
    register-with-eureka: true
    # 是否从EurekaServer抓取已有的注册信息,默认为true;单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
    # 设置于eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
    defaultZone: http://localhost:7001/eureka
  3. applicaiton上加注解

    1
    2
    3
    4
    5
    6
    7
    8
    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentMain8001 {
    public static void main(String[] args) {
    System.out.println("服务运行在 http://localhost:8001/");
    SpringApplication.run(PaymentMain8001.class, args);
    }
    }

为了防止单点故障的问题,这边可以增加一个EurekaServer的实例,从而组成EurekaServer集群,相互注册相互守望。

集群搭建

  1. 先启动eureka注册中心
  2. 启动服务提供者: payment支付服务
  3. 支付服务启动后会把自身信息(比服务地址以别名方式注册进eureka)
  4. 消费者order服务在需要调用接口时,使用服务别名去注册中心获取实际的RPC远程调用地址
  5. 消费者获得调用地址后,底层实际是利用HttpClient术实现远程调用
  6. 消费者获得服务地址后会缓存在本地jvm内存中,默认每间隔30秒更新一次服务调用地址

问题:微服务RPC远程服务调用最核心的是什么?

A: 高可用,试想你的注册中心只有一个ohly one,它出故障了那就呵呵了,这会导致整个为服务环境不可用。 所以解决办法:搭建Eureka注册中心集群,实现负载均衡+故障容错

  1. 创建多个eureka实例工程or模块

  2. 修改hosts映射文件: C:\Windows\System32\drivers\etc\HOSTS

    1
    2
    3

    127.0.0.1 eureka7001.com
    127.0.0.1 eureka7002.com

    虽然eureka7001.com和eureka7002.com都指向的是localhost,真正区分服务的是通过后面的port。但仍然这么做的目的是模拟真实情况,不然都是localhost的话对用户而言不好区分。

  3. 修改yml配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server:
    port: 7002

    eureka:
    instance:
    hostname: eureka7002.com
    client:
    # 表示不向注册中心注册自己
    register-with-eureka: false
    # 自己就是注册中心,职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    # 7001指向7002(即在7002中注册了7001的地址)
    defaultZone: http://eureka7001.com:7001/eureka/
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    server:
    port: 7001

    eureka:
    instance:
    hostname: eureka7001.com
    client:
    # 表示不向注册中心注册自己
    register-with-eureka: false
    # 自己就是注册中心,职责就是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
    defaultZone: http://eureka7002.com:7002/eureka/

    两个server相互存了对方的地址,相互守望从而实现高可用

同时运行两个application,然后输入localhost:7001,可以看到页面中DS Replicas显示有7002,打开localhost:7002同样能看到7001的DS Replicas即镜像

服务接入集群

修改配置文件,主要是把集群中的地址全部填上

1
2
3
4
5
6
7
8
eureka:
client:
# 表示不向注册中心注册自己, 默认为true
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true;单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka

服务负载均衡

Author: Mrli

Link: https://nymrli.top/2021/12/29/SpringCloud笔记/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
Spring中的Bean
NextPost >
使用七牛云作图床+PicGo
CATALOG
  1. 1. MVN配置
  2. 2. 业务开发流程
  3. 3. 请求模拟
  4. 4. 注解使用
  5. 5. 添加热部署
  6. 6. RestTemplate
  7. 7. 注册中心
  8. 8. eureka环境搭建
    1. 8.1. 服务端server
    2. 8.2. 客户端client
    3. 8.3. 集群搭建
      1. 8.3.1. 服务接入集群
    4. 8.4. 服务负载均衡