springboot第45集:微服务iot与小程序关联

开发环境

  • Java JDK 1.8 Java SE Development Kit 8 Downloads(opens new window)

  • Maven 3.8 Installing Apache Maven(opens new window)

  • Mac : Docker Desktop For Mac(opens new window)

  • Windows : Docker Desktop For Windows(opens new window)

**使用 Taro.redirectTo 替代 Taro.navigateTo**: 在退出登录的按钮点击事件处理函数中,使用 Taro.redirectTo 而不是 Taro.navigateTo 来导航到登录页面。这将替换当前页面,使用户无法通过返回按钮返回到之前的页面。

d539c3e246e545636e59b4c83d965264.png
image.png
MAC系统 JDK 卸载及彻底删除

▌1.删除运行路径和运行环境等

sudo rm -fr /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
sudo rm -fr /Library/PreferencesPanes/JavaControlPanel.prefPane
sudo rm -fr ~/Library/Application\ Support/Java

▌2.删除当前版本的jdk

sudo rm -rf /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk

(注:不确定版本号先查看当前版本 ls /Library/Java/JavaVirtualMachines/

▌3.检查是否卸载成功

java -version

在 macOS 上切换 Java 版本通常涉及到使用 java_home 或其他工具来选择要使用的 Java 版本。以下是一些常见的步骤:

  1. 使用 java_home

    macOS 提供了 java_home 命令,可以用来切换 Java 版本。打开终端应用(Terminal)并执行以下命令:

  • 查看已安装的 Java 版本:

    /usr/libexec/java_home -V

    这将列出你系统上已安装的 Java 版本及其标识。

  • 切换到特定版本(例如 Java 11):

    export JAVA_HOME=`/usr/libexec/java_home -v 11`

    这会将 JAVA_HOME 环境变量设置为 Java 11 的安装路径。你可以根据你的需求替换版本号。

使用 Homebrew(仅适用于 OpenJDK):

如果你使用 Homebrew 来安装 OpenJDK,你可以使用 brew 命令来切换版本。

  • 安装 OpenJDK:使用 Homebrew 安装你需要的 OpenJDK 版本。

    brew install openjdk@11  # 安装 OpenJDK 11
  • 切换版本:使用 brew link 命令来切换已安装的 OpenJDK 版本。

    brew link --overwrite openjdk@11  # 切换到 OpenJDK 11

如果你希望查看 Homebrew 的安装目录,可以打开终端并运行以下命令:

brew --prefix

EMQX

大规模分布式 MQTT 消息服务器

  • 基于 APL 2.0 开放源码协议

  • 完整 MQTT 3.x 和 5.0 规范

  • Masterless 高可用集群架构

  • 高并发、低时延、高性能

  • 可扩展的网关和插件体系

CentOS/RHEL

配置 EMQX Yum 源

curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash

安装 EMQX

sudo yum install emqx -y

启动 EMQX

sudo systemctl start emqx
9eedf795e3640be8518c3a152a1e8f1a.png
image.png
b10fd6405ed288bdf3832848fb5beb02.png
image.png
5ddb2d502fa3a0e817d67a97b2fb4f25.png
image.png
1cc6caeae156391d79820f4d882fa513.png
image.png
47192770842934aa0855c0a1396f7aed.png
image.png
103fa11dfd9f5609a3a8276d9dba70ce.png
image.png
d23a986fc1157f96755a2e6543010e67.png
image.png
18227b40ebe38e26696be41be80dbfa5.png
image.png
04a96fdc503312b0ebcf97b79f5c4783.png
image.png
26cf6b53d6453137b18174797ead18ca.png
image.png
cdd863647b0537d1e954decdf1ec3efe.png
image.png
9a4ed34b7e672acb9661822d420a644a.png
image.png
84430026985274c983d2703a5c2cca4f.png
image.png
fe13f55b13123febc9bf7a46bf1774b6.png
image.png
590cab7a8b13299f4540452f9c998291.png
image.png
a68439804b11d79840f0231e04e69859.png
image.png
@ApiModelProperty(value = "业务:")
@ApiModelProperty(value = "组织ID过滤集")//权限过滤
private List<String> orgIds;
@ApiModelProperty(value = "组织序号过滤集")//权限过滤
private List<Integer> oNums;
@ApiModelProperty(value = "Cassandra分页标签")
private String pageStateStr;
7403f8b432405a12a76a8c878f545393.png
image.png
057d1aa5daa56b7c4b59a6c9fb5b26ab.png
image.png
893a011bd3cb1c994b24a5669d66c33d.png
image.png
d86e71e1f5d3ca5a1231aa94479dea7c.png
image.png

cd /usr/lib/emqx/bin

启动EMQ X

进入解压出的文件夹:

cd emqx

然后使用如下命令启动emqx:

sudo ./bin/emqx start
查询一下emqx的状态,检查一下是否真正成功启动:
sudo ./bin/emqx_ctl status
ff80c3070a74d26823d195d0e3ec9a33.png
image.png

admins

用于创建、修改、删除管理员账户,子命令如下:

命令 描述
admins add 添加 Dashboard 用户
admins passwd 重置 Dashboard 指定用户的密码
admins del 删除指定 Dashboard 用户
eb1cb00c651da9aa45d22c41fe87f221.png
image.png
8ae2f697907c26ffe0e893dc3e115767.png
image.png
version: '3'
services:
  kafka:
    container_name: ${CONTAINER_NAME}
    restart: always
    environment:
      ALLOW_PLAINTEXT_LISTENER: 'yes'
      KAFKA_CFG_LOG_RETENTION_MS: 60000
      KAFKA_CFG_MAX_REQUEST_SIZE: 524288000
      KAFKA_CFG_MESSAGE_MAX_BYTES: 524288000
      KAFKA_CFG_REPLICA_FETCH_MAX_BYTES: 524288000
      KAFKA_CFG_FETCH_MESSAGE_MAX_BYTES: 524288000
      KAFKA_CFG_PARTITION_FETCH_BYTES: 524288000
      KAFKA_CFG_NODE_ID: 0
      KAFKA_CFG_PROCESS_ROLES: controller,broker
      KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
      KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://${CONTAINER_NAME}:${PANEL_APP_PORT_HTTP}
      KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: [email protected]:9093
      KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
    networks:
      - 1panel-network
    ports:
      - "${PANEL_APP_PORT_HTTP}:9092"
    image: bitnami/kafka:3.6.0
    labels:
      createdBy: "Apps"
networks:  
  1panel-network:  
    external: true

9092

version: '3'
services:
  memos:
    image: neosmemo/memos:0.17.0
    container_name: ${CONTAINER_NAME}
    restart: always
    networks:
      - 1panel-network
    ports:
      - ${PANEL_APP_PORT_HTTP}:5230
    volumes:
      - ./memos:/var/opt/memos
    labels:
      createdBy: "Apps"
networks:
  1panel-network:
    external: true
5227b64f39155413b7e734afd0258963.png
image.png

并发,指的是多个事情,在同一时间段内同时发生了。  并行,指的是多个事情,在同一时间点上同时发生了。 只有在多CPU的情况中,才会发生并行。 否则,看似同时发生的事情,其实都是并发执行的。

Redis作为一款高性能的NoSQL数据库,具备快速读写、高并发、数据持久化等特点,非常适合用于实现延迟队列。Redis提供了丰富的数据结构,其中利用Redis的ZSET(有序集合)数据结构就可以实现一个简单的延迟队列。

Redis的zset数据结构中的每个元素都有一个分数score和一个值value,我们可以将任务的执行时间戳作为score,将任务数据作为value,将任务插入到zset中,每个任务有一个唯一的id(比如订单id),以及任务执行时间(比如30min),任务内容(比如订单超时支付系统自动取消)等信息体。然后另起一个线程,该线程会周期性地从zset中取出score最小(即最早要执行的)的任务,如果该任务的score小于当前时间戳,则执行任务,否则等待一段时间再次检查,直到任务可以执行,执行任务后,通过Redis的remove命令删除已经成功执行的任务即可。

如何利用Redis实现延迟队列的一些实现步骤?同学们请看:

引入spring-boot-starter-data-redis 和spring-boot-starter-test依赖。

配置redis。

创建消息类 DelayMessage

编写延时队列类 DelayQueue,提供添加消息、删除消息和获取消息方法。

创建消息处理器 DelayMessageHandler,处理已到期的消息。

编写测试类 DelayQueueTest,测试延时队列的添加、删除和处理消息功能。

在Spring Boot启动类中启动延时队列。

测试用例方法启动测试。

6d64456b4e97e9fdf709ed58bbc1f4c7.png
image.png
645bcc29cdbd7f97ad9358f50bf3cb7f.png
image.png

@AllArgsConstructor@NoArgsConstructor 是 Java 中的注解,通常与 Lombok 库一起使用。它们有助于减少 Java 类中的样板代码。

  1. **@AllArgsConstructor**:

    @AllArgsConstructor
    public class MyClass {
        private String field1;
        private int field2;
    }
    public MyClass(String field1, int field2) {
        this.field1 = field1;
        this.field2 = field2;
    }
  • Lombok 将生成如下构造函数:

  • 为类中的所有字段生成一个带有参数的构造函数。

  • 当你希望有一个一次性初始化所有字段的构造函数时很有用。

  • 例如:

**@NoArgsConstructor**:

@NoArgsConstructor
public class MyClass {
    private String field1;
    private int field2;
}
public MyClass() {
    // 无参数的默认构造函数
}
  • Lombok 将生成如下构造函数:

  • 为类生成一个无参数的默认构造函数。

  • 当需要一个无参数构造函数时很有用,例如在使用需要它的框架或库时。

  • 例如:

使用这些注解,你可以减少在 Java 类中手动编写构造函数的需求,使你的代码更为简洁和可读。请注意,要使用 Lombok,你需要在项目中包含 Lombok 库。

033ddef427b267a861bb99e65bee5bb8.png
image.png
@Component
public class DelayQueue {

    private static final String KEY = "delay_queue";

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加消息到延时队列中
     */
    public void put(DelayMessage message) {
        redisTemplate.opsForZSet().add(KEY, message, message.getExpireTime());
    }

    /**
     * 从延时队列中删除消息
     */
    public void remove(DelayMessage message) {
        redisTemplate.opsForZSet().remove(KEY, message);
    }

    /**
     * 获取延时队列中已到期的消息
     */
    public List<DelayMessage> getExpiredMessages() {
        long minScore = 0;
        long maxScore = System.currentTimeMillis();
        Set<Object> messages = redisTemplate.opsForZSet().rangeByScore(KEY, minScore, maxScore);
        if (messages == null || messages.isEmpty()) {
            return Collections.emptyList();
        }
        List<DelayMessage> result = new ArrayList<>();
        for (Object message : messages) {
            result.add((DelayMessage) message);
        }
        return result;
    }

}
@Component
public class DelayMessageHandler {

    @Autowired
    private DelayQueue delayQueue;

    /**
     * 处理已到期的消息(轮询)
     */
    @Scheduled(fixedDelay = 1000)
    public void handleExpiredMessages() {
        //获取当前系统时间
        String dateTime = DateFormatUtils.format(new Date(), "hh:MM:ss");

        //扫描任务,并将需要执行的任务加入到任务队列中
        List<DelayMessage> messages = delayQueue.getExpiredMessages();
        System.out.println(dateTime + " 待处理消息:" + messages);
        //处理消息
        if (!messages.isEmpty()) {
            for (DelayMessage message : messages) {
                System.out.println(dateTime + " 处理消息:" + message.getContent());
                //成功处理消息后,便将消息进行移除。
                delayQueue.remove(message);
            }
        }
    }

}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DelayQueueTest {
    @Autowired
    private DelayQueue delayQueue;

    @Test
    public void testDelayQueue() {
        //获取当前系统时间
        long newDate = System.currentTimeMillis();
        
        // 添加消息:1秒后到期
        DelayMessage message1 = new DelayMessage("1", "delay message 1", newDate + 1000);
        // 添加消息:3秒后到期
        DelayMessage message2 = new DelayMessage("2", "delay message 2", newDate + 3000);
        // 添加消息:6秒后到期
        DelayMessage message3 = new DelayMessage("3", "delay message 3", newDate + 6000);
        // 添加消息:10秒后到期
        DelayMessage message4 = new DelayMessage("4", "delay message 4", newDate + 10000);

        delayQueue.put(message1);//1s后执行
        delayQueue.put(message2);//3s后执行
        delayQueue.put(message3);//6s后执行
        delayQueue.put(message4);//10s后执行
    }
    
}

在前端,你可以使用逗号分隔的字符串表示 List<String>。例如,如果你要传递一个包含三个 SOC 值的列表,可以这样表示:

在这个例子中,前端将 soc 作为一个字符串传递给后端,后端在接收到这个字符串后,可以通过逗号分隔符解析为一个 List<String>。具体的解析方法取决于后端使用的编程语言和框架。例如,在 Java 中,可以使用 String.split 方法将字符串拆分为数组:

String socString = "75,80,60"; List<String> socList = Arrays.asList(socString.split(","));
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> soc0 = null;  // 你的第一个列表
        List<String> soc1 = null;  // 你的第二个列表

        // 合并两个列表成一个
        List<String> combinedList = Stream.of(soc0, soc1)
                .filter(list -> list != null)
                .flatMap(List::stream)
                .collect(Collectors.toList());

        // 打印合并后的列表
        System.out.println(combinedList);
    }
}

Spring如何管理Mybaits的Mapper接口的

  1. 首先MyBatis的Mapper接口核心是JDK动态代理

  2. Spring会排除接口,无法注册到IOC容器中

  3. MyBatis实现了BeanDefinitionRegistryPostProcessor可以动态注册BeanDefinition

  4. 需要自定义扫描器(继承Spring内部扫描器ClassPathBeanDefinitionScanner)重写排除接口的方法(isCandidateComponent)

  5. 但是接口虽然注册成了BeanDefinition但是无法实例化Bean,因为接口无法实例划

  6. 需要将BeanDefinition的BeanClass替换成JDK动态代理的实例

  7. Mybatis通过FactoryBean的工厂方法设计模式可以自由控制Bean的实例划过程,可以在getObject方法中创建JDK动态代理

过程

  1. 读取配置信息(xml javaconfig)api: BeanDefinitionReader

  2. 解析配置:解析@ComponentScan @Bean @Configuration @Import 目的:为了注册BeanDefinition

  3. @ComponentScan解析:扫描制定包的路径所有.class类 api:ClassPathBeanDefinitionSacnner

    1. 判断类上面是否有@Component

    2. 判断你的类是否接口、抽象类

MyFactoryBean

阿里微服务Spring Cloud Alibaba 三高架构实战

58d57912a76d61e476aecfde0d79aa38.png
image.png
StockController.java
@RestController
@RequestMapping("/stock")
public class StockController {
 @Autowired
 private StockService stockService;
 @Autowired
 private Registration registration;
 @GetMapping(value = "/deduct/{productId}/{stockCount}")
 public String deductStock(@PathVariable("productId") Long productId,
                           @PathVariable("stockCount") Integer stockCount) {
  return stockService.deductStock(productId, stockCount); 
 }
 @GetMapping("/getIpAndPort")
 public String getIpAndPort() {
  return registration.getHost() + ":" + registration.getPort();
 }
}
f97004ff5f778ab6d2d2e67738e8dc5c.png
image.png
c4b981c5147bb78e43095fa5a8711b44.png
image.png
@GetMapping(value = "/create")
public String createOrder(@RequestParam("productId") Long productId, @RequestParam("userId") Long userId, @RequestParam("stockCount") Integer stockCount, @RequestParam("creditCount") Integer creditCount) {
 orderService.createOrder(productId, userId, stockCount, creditCount);
 return "success";
}
a84ca870860d7dd24b85f4bfe72cb1cd.png
image.png
473c5b710106e204dd60b1cd310fac1d.png
image.png
f8c0ba07c6dcf9a27b6ccef006c5c90f.png
image.png

组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

RocketMQ: 一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud OSS:阿里云对象储存服务(Object Storage Service,简称OSS),是阿里云提供的海量、安全、低成本、高可靠的云储存服务。您可以在任何应用、任何时间、任何地点储存和访问任意类型的数据。

Alibaba Clound SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级,精准,高可靠,高可用的定时(基于Cron表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好,高效,智能的互联网通讯能力,帮助企业迅速搭建客户接触通道。

19d6ddcc68574f0d6d3c3a1cb40c442d.png
image.png
b3ec2f0dfbe4a2a886319f0d3ef6837a.png
image.png
d7a8346aada4b89fee7d703ff57061a3.png
image.png

限流,熔断,降级

30-60w程序员

  1. 掌握操作系统原理,Linux核心开发技能,计算网络与IO底层原理,必备做数据结构与算法

  2. 掌握常用框架SSM以及Spring Boot核心功能以及源码级架构原理

  3. 掌握常用设计模式以及在实际开发场景中的应用

  4. 掌握多线程并发编程核心原理,具备开发高性能高并发程序能力

  5. 掌握JVM,Mysql,Tomcat,Nginx等技术的核心原理以及性能调优

  6. 掌握分布式缓存,MQ,搜索,分布式调度,RPC通信,海量数据分库分表等中间件核心功能与原理

  7. 掌握微服务架构Spring Cloud以及阿里微服务全栈技术功能与架构原理

  8. 具备一定海量数据处理以及架构能力

  9. 具备一定大型互联网系统设计,开发以及架构实战经验

43816305fd93fa8718a150cab2e56933.png
image.png
0181ac5c150b61dfd362a79c5b1b7545.png
image.png
f930c72ed37ba6ab01c263c64ccc931f.png
image.png

描述Spring的Aop的完整实现流程?

Aop的实现大致分为三大步:

当@EnableAspectJAutoProxy会通过@Import注册一个BeanPostProcessor处理AOP

  1. 在创建Bean时调用BeanPostProcessor解析切面@Aspect,将切面中所有的通知解析为advisor(该对象包含通知,切点,通知方法)排好序放入List并缓存。

  2. 在Bean初始化后调用BeanPostProcessor拿到之前缓存的advisor判断当前Bean是否被切点表达式命中,如果匹配为Bean创建动态代理。

  3. 调用:通过之前创建的动态代理 调用方法 执行增强,通过调用链设计模式依次调用通知方法。

f518c38f1b832440aa48636d89bde1ba.png
image.png
eb31023948a0a8f868ac197a4527bc2f.png
image.png
ae4a3ba5b97d0f73cff444d61395218a.png
image.png
12940f471fea66b0b7254d81fb79dfd8.png
image.png
b98f493a95fdad91c3f743b2946d27ab.png
image.png
7b6774ac1edf4363ef8faecf21ce6556.png
image.png
afc299621d9301d08205072c63fb73a3.png
image.png
50c43384f1f2b14b8591f45713b049c0.png
image.png
9f278a3eed19f4094e9386fde3280320.png
image.png
20131bccfca24b52e905e3124a61792e.png
image.png
55dd05d991e0eda50954f2960a73bbc7.png
image.png
4b761b30f7843a41d4f9b609d1e2a8e2.png
image.png
3d9dc3a7def554424416e6714deb5e69.png
image.png
3ebaa547449d57522837e8975fbb9d1c.png
image.png
c3a39008300cca6bc0dc231be92046a0.png
image.png
c07ccd35d753c6b9b3ce9dd542ba0d19.png
image.png
6cd586fe8a44ba51e9eddd128003bcec.png
image.png
87471aa78ecc549bce8d036a09e83b03.png
image.png
530a98ffed2c10708a2a3b0b0d4213f4.png
image.png
09d887e4bdafc0b4cfbd7ffb016d644a.png
image.png
395898714802a4cddaa62ecec785d287.png
image.png
9c21fe32bbdbd7958e6bb80cd1de5167.png
image.png
ac969da257c50f57371ac29feee22d05.png
image.png
1a7cff0ee101f74ade41e9aed95cca18.png
image.png
ce485421e86843e32aeb342fd2d0a681.png
image.png
df4618dc67f970c10f020d2286d7d349.png
image.png

f2786ece5a7854491aee6d385e44069c.pngALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

# MySQL8: Client does not support authentication protocol requested by server
ALTER USER 'customuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
FLUSH PRIVILEGES;

在 Spring Boot 中查询附近的数据通常涉及到地理位置的计算。你可以选择在 MySQL 中使用空间函数,也可以使用 Elasticsearch(ES)进行地理位置的索引和查询。

使用 MySQL 实现:

  1. 数据库表设计: 在你的表中添加经度和纬度字段,这两个字段用于存储地理位置信息。

    CREATE TABLE your_table (
        id INT PRIMARY KEY,
        name VARCHAR(255),
        latitude DOUBLE,
        longitude DOUBLE
    );
  2. 查询附近的数据: 使用 MySQL 的空间函数,比如 ST_Distance,来计算距离。以下是一个简单的例子:

    SELECT id, name, latitude, longitude,
           ST_Distance(
               POINT(your_latitude, your_longitude),
               POINT(latitude, longitude)
           ) AS distance
    FROM your_table
    HAVING distance <= 50
    ORDER BY distance;

    替换 your_latitudeyour_longitude 为你的当前位置的经度和纬度。

使用 Elasticsearch 实现:

  1. 安装 Elasticsearch: 首先确保你已经安装并启动了 Elasticsearch。

  2. 索引数据: 在索引中添加地理位置映射:

    PUT /your_index
    {
      "mappings": {
        "properties": {
          "location": {
            "type": "geo_point"
          }
        }
      }
    }

    保证你的文档包含一个 location 字段,其值为经纬度数组。

  3. 查询附近的数据: 使用 Elasticsearch 的地理位置查询。以下是一个例子:

    SearchRequest searchRequest = new SearchRequest("your_index");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
    GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location")
            .point(your_latitude, your_longitude)
            .distance(50, DistanceUnit.KILOMETERS);
    
    searchSourceBuilder.query(queryBuilder);
    searchRequest.source(searchSourceBuilder);
    
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    替换 your_latitudeyour_longitude 为你的当前位置的经度和纬度。

d3cc4bb0a922ab4432f4f55219df27e7.png
image.png
// const AMap = (window as any).AMap
    // const moveAnimation = new AMap.moveAnimation({
    //  marker: marker.value,
    //  path: lineArr.value,
    //  duration: 500
    // })
    // moveAnimation.start();
faf5c3cfd46bde88df915cba47a6e9aa.png
image.png
5f37666684eef67a93fb844c0ec4c12b.png
image.png
ed4b1d89d0e0060fb701ca2c9c00c356.png
image.png
3f43bf2db400c2da512b89efe483ddf3.png
image.png

常见微服务架构

  1. dubbo: zookeeper +dubbo + SpringMVC/SpringBoot 配套 通信方式:rpc 注册中心:zookeeper / redis 配置中心:diamond

  2. SpringCloud:全家桶+轻松嵌入第三方组件(Netflix) 配套 通信方式:http restful 注册中心:eruka / consul 配置中心:config 断 路 器:hystrix 网关:zuul 分布式追踪系统:sleuth + zipkin

Spring Cloud Alibaba 是所有的实现方案中功能最齐全的。尤其是在 Netflix 停止更新了以后,Spring Cloud Alibaba 依然在持续更新和 迭代。

高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务. 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道. 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时任务调度服务. Nacos Service Discovery 通过nacos实现的服务发现平台. Spring Cloud Alibaba Sentinel 提供 Sentinel 自动接入和配置支持,提供 Spring Web/WebFlux、Feign、RestTemplate、注解等适配 Spring Cloud Alibaba Sentinel DataSource 提供 Sentinel 动态数据源接入支持,方便用户整合 Nacos 等数据源动态管理规则 Spring Cloud Alibaba Sentinel Gateway 提供 Sentinel 网关流控自动接入支持,目前支持 Spring Cloud Gateway 和 Zuul 阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案. 一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务. 通过Alibaba Nacos实现配置管理:支持分布式系统中的外部化配置、配置更改时自动刷新功能 Lombok Java 注释库有助于减少样板代码。 Spring Web 使用 Spring MVC 构建 Web,包括 RESTful 应用程序。使用 Apache Tomcat 作为默认嵌入式容器。 Spring Session 提供用于管理用户会话信息的 API 和实现。 Spring Security 用于 Spring 应用程序的高度可定制的身份验证和访问控制框架。 MyBatis Framework 持久性框架,支持自定义 SQL、存储过程和高级映射。 MyBatis 使用 XML 描述符或注释将对象与存储过程或 SQL 语句结合起来。 MySQL 驱动程序 MySQL JDBC 和 R2DBC 驱动程序。 Spring Data Redis (Access+Driver) 高级且线程安全的 Java Redis 客户端,用于同步、异步和反应式使用。支持集群、哨兵、管道、自动重新连接、编解码器等。 Spring Data Elasticsearch (Access+Driver) 使用 Spring Data Elasticsearch 的分布式 RESTful 搜索和分析引擎。 Spring Data for Apache Cassandra 一个免费开源的分布式 NoSQL 数据库管理系统,提供高可扩展性和高性能。 Spring Data Reactive for Apache Cassandra 以响应方式访问 Cassandra NoSQL 数据库。 Spring for Apache Kafka 发布、订阅、存储,并处理记录流。 Spring for RabbitMQ 为您的应用程序提供一个发送和接收消息的通用平台,并为您的消息提供一个安全的存放位置,直到收到为止。 Spring for Apache Kafka Streams 使用 Apache Kafka Streams 构建流处理应用程序。 WebSocket 使用 SockJS 和 STOMP 构建 WebSocket 应用程序。 Quartz Scheduler 使用 Quartz 安排作业。 分布式跟踪 在日志中启用跨度和跟踪 ID。 Spring REST 文档通过结合使用 Asciidoctor 手写和使用 Spring MVC Test 生成的自动生成的片段来记录 RESTful 服务。 网关 提供一种简单而有效的方法来路由到 API 并为它们提供横切关注点,例如安全性、监控/指标和弹性。 OpenFeign 声明式 REST 客户端。 OpenFeign 创建一个用 JAX-RS 或 Spring MVC 注释修饰的接口的动态实现。 Cloud LoadBalancer 使用 Spring Cloud LoadBalancer 进行客户端负载均衡。

f4133c766ce7868bff8250e9056296f2.png
image.png
db.createUser(
   {
     user: "gd",
     pwd: "123456",
     roles: [ { role: "readWrite", db: "base_db" } ]
   }
)

问题

单点容错率低 & 无法针对不同模块进行针对性优化和水平扩展 & 系统间耦合度变高 & 一个调度中心对集群进行实时管理 & 资源调度和治理中心(SOA Service Oriented Architecture) & 服务间会有依赖关系,一旦某个环节出错会影响较大( 服务雪崩 ) & 服务关系复杂,运维、测试部署困难 & 微服务架构比 SOA架构粒度会更加精细,让专业的人去做专业的事情(专注),目的提高效率,每个服务于服务之间互不影响,微服务架构中,每个服务必须独立部署,微服务架构更加轻巧,轻量级 & SOA 架构中可能数据库存储会发生共享,微服务强调独每个服务都是单独数据库,保证每个服务于服务之间互不影响。 & 项目体现特征微服务架构比 SOA 架构更加适合与互联网公司敏捷开发、快速迭代版本,因为粒度非常精细 & 分布式系统开发的技术成本高(容错、分布式事务等)& 各个微服务进行分布式独立部署,当进行模块调用的时候,分布式将会变得更加麻烦。

这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])     nacos

这么多小服务,他们之间如何通讯?(restful rpc dubbo feign)

这么多小服务,客户端怎么访问他们?(网关)     gateway

这么多小服务,一旦出现问题了,应该如何自处理?(容错)     sentinel

这么多小服务,一旦出现问题了,应该如何排错? (链路追踪)   skywalking

加群联系作者vx:xiaoda0423

仓库地址:https://github.com/webVueBlog/JavaGuideInterview

猜你喜欢

转载自blog.csdn.net/qq_36232611/article/details/134985784
今日推荐