当前位置: 首页 > news >正文

redisson常用APi-Example

中文文档目录

redisson中文文档目录

分布式对象

package com.example.redissondemo.test;import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** 测试学习redisson 对象 api*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonObjectExampleTests {@Autowiredprivate RedissonClient redissonClient;/*** 直接存储对象,无需强制类型转换 (支持异步操作)*/@Testpublic void bucketTest() {RBucket<Order> orderBucket = redissonClient.getBucket("myOrder");System.out.println("init : " + orderBucket.get());// 设置orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);System.out.println("设置 : " + orderBucket.get());// 删除System.out.println("删除状态:" + orderBucket.delete() + "当前" + orderBucket.get());// 重新设置orderBucket.set(new Order(10L, "OR001"), 1, TimeUnit.MINUTES);System.out.println("重新设置 : " + orderBucket.get());// 如果是or1 改为or2orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR002"));System.out.println("存在or1 改为or2 : " + orderBucket.get());// 如果是or1 改为or3orderBucket.compareAndSet(new Order(10L, "OR001"), new Order(10L, "OR003"));System.out.println("存在or1 改为or3 : " + orderBucket.get());// 存在bucket对象就修改为OR3orderBucket.setIfExists(new Order(10L, "OR003"), 1, TimeUnit.MINUTES);System.out.println("存在bucket对象就修改为OR3 : " + orderBucket.get());orderBucket.isExists();orderBucket.delete();}/*** 数字操作,计数器 原子类操作 等等 (支持异步操作)** @throws ExecutionException* @throws InterruptedException* @throws TimeoutException*/@Testpublic void numberTest() throws ExecutionException, InterruptedException, TimeoutException {// 存在精度丢失RDoubleAdder doubleAdder = redissonClient.getDoubleAdder("doubleAdder");doubleAdder.add(1.9999);doubleAdder.add(2.0001);doubleAdder.add(3.0000000000000001);RFuture<Double> future = doubleAdder.sumAsync();Double sum = future.get(1000, TimeUnit.MILLISECONDS);System.out.println(sum);doubleAdder.delete();RLongAdder longAdder = redissonClient.getLongAdder("longAdder");longAdder.add(100);longAdder.increment();longAdder.increment();long longSum = longAdder.sum();System.out.println(longSum);longAdder.delete();longAdder.destroy();// 当不再使用整长型累加器对象的时候应该自行手动销毁,如果Redisson对象被关闭(shutdown)了,则不用手动销毁// 支持CAS设置RAtomicDouble atomicDouble = redissonClient.getAtomicDouble("atoDouble");double v = atomicDouble.incrementAndGet();System.out.println(v);atomicDouble.compareAndSet(v, 2.0);System.out.println(atomicDouble.get());atomicDouble.delete();RLongAdder atoLong = redissonClient.getLongAdder("atoLong");atoLong.increment();System.out.println(atoLong.sum());atoLong.delete();}/*** 限流**/@Testpublic void rateLimiterTest() {RRateLimiter limiter = redissonClient.getRateLimiter("orderImport");// 初始化// 最大流速 = 每1秒钟产生10个令牌// tryAcquire 尝试获取令牌// 如果令牌足够 则扣减令牌 返回true// 如果令牌不够 则不扣减  返回false// acquire 直接获取令牌 如果获取不到令牌 就阻塞等新的令牌产生// 如果令牌足够 则扣减对应的令牌// 如果令牌不够 则扣减令牌数量为0limiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.HOURS);boolean b = limiter.tryAcquire(1);System.out.println(" tryAcquire 1  availablePermits : " + limiter.availablePermits());b = limiter.tryAcquire(10);System.out.println(" tryAcquire 10 availablePermits : " + limiter.availablePermits());limiter.acquire(3);System.out.println("acquire 3 availablePermits : " + limiter.availablePermits());new Thread(() -> {limiter.acquire(2);System.out.println(" acquire 2 availablePermits : " + limiter.availablePermits());}).start();limiter.acquire(7);System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());//        long start = System.currentTimeMillis();limiter.acquire(1);
//        System.out.println(System.currentTimeMillis() - start);System.out.println(" acquire 1 availablePermits : " + limiter.availablePermits());try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}limiter.acquire(7);System.out.println(" acquire 7 availablePermits : " + limiter.availablePermits());limiter.delete();}@Testpublic void mapDemo() {
//        RMap<String, String> test = redissonClient.getMap("test", MapOptions.defaults());
//        test.put("testKey", "testValue");
//        test.fastPut("fastTestKey", "testValue");
//        String testKey = test.get("testKey");
//        test.remove("testKey");
//        test.get("testKey");RBucket<MyBucket> myBucket = redissonClient.getBucket("myBucket");myBucket.set(new MyBucket(), 1, TimeUnit.MINUTES);System.out.println(myBucket.get());myBucket.rename("myBucket1");RBucket<MyBucket> myBucket1 = redissonClient.getBucket("myBucket");System.out.println(myBucket1.get());RBucket<MyBucket> myBucket2 = redissonClient.getBucket("myBucket1");System.out.println(myBucket2.get());}@Datapublic static class MyBucket {private String name = "test";private int age = 10;}}

分布式集合

package com.example.redissondemo.test;import com.alibaba.fastjson.JSONObject;
import com.example.redissondemo.RedissonDemoApplication;
import com.example.redissondemo.test.domain.Order;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;/*** 测试学习redisson 集合 api*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RedissonDemoApplication.class)
@Slf4j
public class RedissonCollectionsExampleTests {@Autowiredprivate RedissonClient redissonClient;/***  Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。*  还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口**/@Testpublic void mapTest() throws ExecutionException, InterruptedException {String key = "user";RMap<String, String> map = redissonClient.getMap(key);map.put("name", "zhangsan");map.put("age", "18");String name = map.get("name");System.out.println ("user name : " + name);boolean b = map.containsKey("age");System.out.println("has age ? : " + b);Set<Map.Entry<String, String>> entries = map.entrySet();System.out.println(Arrays.toString(entries.toArray()));map.remove("age");// fastPut 和 put 的区别就是 put会发回之前该索引位置的值(如果存在) 而fastPut 只会返回插入成功与否map.fastPut("like", "eat");System.out.println(JSONObject.toJSONString(map));// 同理map.fastRemove("like");// 异步操作 提高操作效率RFuture<String> putAsyncFuture = map.putAsync("321","");RFuture<Boolean> booleanRFuture = map.fastPutAsync("123", "");putAsyncFuture.get();booleanRFuture.get();System.out.println(JSONObject.toJSONString(map));}/*** 多值映射 一对多映射关系的存储* 基于list  set*/@Testpublic void myMultimapTest(){// 基于set 基于Set的Multimap不允许一个字段值包含有重复的元素。RSetMultimap<String, String> map = redissonClient.getSetMultimap("RSetMultimap");map.put("age", "19");map.put("age", "20");map.put("name", "zhangsan");Set<String> allValues = map.get("age");System.out.println(allValues);List<String> newValues = Arrays.asList("17", "16", "15");Set<String> oldValues = map.replaceValues("age", newValues);System.out.println(oldValues);Set<String> removedValues = map.removeAll("age");System.out.println(removedValues);map.put("carCount", "2");Set<Map.Entry<String, String>> entries = map.entries();System.out.println(JSONObject.toJSONString(entries));map.delete();// 基于list 同理 基于List的Multimap在保持插入顺序的同时允许一个字段下包含重复的元素。redissonClient.getListMultimap("myListMultimap");//  Multimap对象的淘汰机制是通过不同的接口来实现的。它们是RSetMultimapCache接口和RListMultimapCache接口,分别对应的是Set和List的Multimaps。RListMultimapCache<Object, Object> myListMultimap2 = redissonClient.getListMultimapCache("myListMultimap2");myListMultimap2.expireKey("2", 10, TimeUnit.MINUTES);RSetMultimapCache<Object, Object> getSetMultimapCache = redissonClient.getSetMultimapCache("getSetMultimapCache");getSetMultimapCache.expireKey("2", 10, TimeUnit.MINUTES);}/*** 基于Redis的Redisson的分布式Set结构的RSet Java对象实现了java.util.Set接口。*/@Testpublic void baseSet(){RSet<Order> set1 = redissonClient.getSet("anySet");set1.add(new Order());set1.remove(new Order());// 基于Redis的Redisson的分布式RSetCache Java对象在基于RSet的前提下实现了针对单个元素的淘汰机制/*** 目前的Redis自身并不支持Set当中的元素淘汰,因此所有过期元素都是通过org.redisson.EvictionScheduler实例来实现定期清理的。* 为了保证资源的有效利用,每次运行最多清理100个过期元素。* 任务的启动时间将根据上次实际清理数量自动调整,间隔时间趋于1秒到2小时之间。* 比如该次清理时删除了100条元素,那么下次执行清理的时间将在1秒以后(最小间隔时间)。* 一旦该次清理数量少于上次清理数量,时间间隔将增加1.5倍。*/RSetCache<Object> set2 = redissonClient.getSetCache("anySet2");// ttl = 10 secondsset2.add(new Order(), 10, TimeUnit.SECONDS);// 基于Redis的Redisson的分布式RSortedSet Java对象实现了java.util.SortedSet接口。在保证元素唯一性的前提下,通过比较器(Comparator)接口实现了对元素的排序。RSortedSet<Integer> set = redissonClient.getSortedSet("anySet");set.trySetComparator(Comparator.comparingInt(a -> a)); // 配置元素比较器set.add(3);set.add(1);set.add(2);set.removeAsync(0);set.addAsync(5);}@Testpublic void baseListAndQueue(){// 基于Redis的Redisson分布式列表(List)结构的RList Java对象在实现了java.util.List接口的同时,确保了元素插入时的顺序。RList<Order> list = redissonClient.getList("anyList");list.add(new Order());Order order = list.get(0);list.remove(new Order());// 队列RQueue<Order> queue1 = redissonClient.getQueue("anyQueue");// 双端队列(DequeRDeque<Order> queue2 = redissonClient.getDeque("anyDeque");// 阻塞队列(Blocking Queue)RBlockingQueue<Order> queue3= redissonClient.getBlockingQueue("anyQueue");// 有界阻塞队列(Bounded Blocking Queue)RBoundedBlockingQueue<Order> queue4 = redissonClient.getBoundedBlockingQueue("anyQueue");// 延迟队列(Delayed Queue)// 基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的RDelayedQueue Java对象在实现了RQueue接口的基础上提供了向队列按要求延迟添加项目的功能。// 该功能可以用来实现消息传送延迟按几何增长或几何衰减的发送策略。RDelayedQueue<Order> delayedQueue = redissonClient.getDelayedQueue(queue1);// 优先队列(Priority Queue)RPriorityQueue<Integer> queue = redissonClient.getPriorityQueue("anyQueue");}}

分布式锁

redisson分布式锁学习

private void redissonDoc() throws InterruptedException {//1. 普通的可重入锁RLock lock = redissonClient.getLock("generalLock");// 拿锁失败时会不停的重试// 具有Watch Dog 自动延期机制 默认续30s 每隔30/3=10 秒续到30slock.lock();// 尝试拿锁10s后停止重试,返回false// 具有Watch Dog 自动延期机制 默认续30sboolean res1 = lock.tryLock(10, TimeUnit.SECONDS);// 拿锁失败时会不停的重试// 没有Watch Dog ,10s后自动释放lock.lock(10, TimeUnit.SECONDS);// 尝试拿锁100s后停止重试,返回false// 没有Watch Dog ,10s后自动释放boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS);//2. 公平锁 保证 Redisson 客户端线程将以其请求的顺序获得锁RLock fairLock = redissonClient.getFairLock("fairLock");//3. 读写锁 没错与JDK中ReentrantLock的读写锁效果一样RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");readWriteLock.readLock().lock();readWriteLock.writeLock().lock();
}

相关文章:

redisson常用APi-Example

中文文档目录 redisson中文文档目录 分布式对象 package com.example.redissondemo.test;import com.example.redissondemo.RedissonDemoApplication; import com.example.redissondemo.test.domain.Order; import lombok.Data; import lombok.extern.slf4j.Slf4j; import o…...

小程序学习(四):WXML模板语法

WXML模板语法-数据绑定 1.数据绑定的基本原则 ①在data中定义数据 ②在WXML中使用数据 2.动态绑定属性 WXML模板语法-事件绑定 3.什么是事件 4.小程序中常用的事件 5.事件对象的属性列表 6.target和currentTarget的区别 7.bindtap的语法格式 8.在事件处理函数中为data中的数据…...

IDEA好用的插件总结

IdeaVim 这个看个人喜好&#xff0c;我比较喜欢用vim&#xff0c;并且支持自定义修改按键绑定alibaba java code guidelines alibaba的java编程规范plantUML 绘制UML&#xff0c;支持语言显示plantUML integration 能够直接将代码转化为UML图&#xff0c;非常方便rainbow brack…...

如何在Linux系统中安装ActiveMQ

1、环境 ActiveMQ是一个纯Java程序&#xff0c;这里安装5.18.2版ActiveMQ&#xff0c;该版MQ运行在JDK 11环境内&#xff0c;为此需要先搭建JDK 11环境&#xff0c;这里安装JDK 15。 1.1、卸载 卸载开源JDK软件包&#xff0c;如下所示&#xff1a; [rootlocalhost ~]# rpm -…...

【Latex】常用公式编辑与符号:公式换行,标号居中、常用符号等

【Latex】常用公式编辑与符号 文章目录 【Latex】常用公式编辑与符号1. 公式换行&#xff0c;且标号居中2. 常用符号3. 常用的希腊字母 1. 公式换行&#xff0c;且标号居中 \begin{equation}\label{eq14} \begin{aligned}a & b/c, \\d & e/f \end{aligned} \end{equ…...

【ArcGIS Pro二次开发】(55):给多个要素或表批量添加字段

在工作中可能会遇到这样的场景&#xff1a;有多个GDB要素、表格&#xff0c;或者是SHP文件&#xff0c;需要给这个要素或表添加相同的多个字段。 在这种情况下&#xff0c;手动添加就变得很繁琐&#xff0c;于是就做了这个工具。 需求具体如下图&#xff1a; 左图是待处理数据…...

CentOS7.3 安装 docker

亲测、截图 阿里云服务器 文章目录 更新源2345 启动开机自启 更新源 sudo yum update -y2 sudo yum install -y yum-utils device-mapper-persistent-data lvm23 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4 sudo yum …...

代码随想录算法训练营第五十二天 | 300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组

文章目录 一、300.最长递增子序列二、674.最长连续递增序列三、718.最长重复子数组 一、300.最长递增子序列 题目链接 代码如下&#xff1a; class Solution { public:int lengthOfLIS(vector<int>& nums) {if (nums.size() < 1) return nums.size();vector<…...

1、Tomcat

java介绍 Java语言和平台由以下几个主要部分组成&#xff1a; 1、Java编程语言(Java Language)&#xff1a;这是Java的核心部分&#xff0c;包括Java语法、关键字、数据类型、运算符、控制结构等。程序员使用Java语言来编写应用程序的源代码。 2、Java开发工具包(Java Developm…...

centos 内网实现mail发送

文章目录 1、frp 穿透公网和内网2、邮件 配置2.1、mail配置文件 3、测试 1、frp 穿透公网和内网 参考地址&#xff1a;https://zhaosongbin.blog.csdn.net/article/details/88865890 frps端部署在内网&#xff0c;frpc端部署在外网 frps端配置和上面文章中的一样&#xff0c…...

【雕爷学编程】MicroPython动手做(25)——语音合成与语音识别2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

如何用C#实现上位机与下位机之间的Wi-Fi通信?

有IP协议支持的话用UDP报文或者TCP直接发IP地址和端口不行么&#xff1f;你说的WiFi难道是2.4GHz频率模块那种东东&#xff1f; 你既然用了wifi&#xff0c;那么只要上位机和下位机的对应wifi网卡都具有ip地址以及其协议支持&#xff0c;那么和网络编程没啥子明显区别的吧………...

学习笔记|大模型优质Prompt开发与应用课(二)|第五节:只需3步,优质Prompt秒变应用软件

原作者&#xff1a;依依│百度飞桨产品经理 一乔│飞桨开发者技术专家 分享内容 01:大模型应用简介 02:LLM应用开发范式 03: Al Studio大模型社区 04:AI对话类应用开发技巧 大模型技术爆发&#xff0c;各类应用产品涌现 文心产业级知识增强大模型 工作中的“超级助手”—…...

VB客运中心汽车售票管理系统设计与实现

摘 要:该系统是信息管理系统在售票管理方面的一个分支和具体运用,是为长治客运中心而设计的管理售票、车次、票价及客票收入统计等日常事物的系统。此系统选择Visual Basic 6.0作为开发工具来实现客运中心汽车售票所要求的各种功能。本文主要介绍了开发此管理系统的背景、必要…...

计算机网络——学习笔记

付费版&#xff1a;直接在上面的CSDN资源下载 免费版&#xff1a;https://wwsk.lanzouk.com/ijkcj13tqmyb 有疑问或者错误的地方可以在评论区指出&#xff0c;我会尽快回复 示例图&#xff1a;...

JSON对象

目录 简介 创建对象 ​编辑json对象作为属性值 json用于交换数据 简介 json&#xff1a;javascript object notation(js标记对象)是一种轻量化的数据交换模式&#xff0c;特点&#xff1a;体积小&#xff0c;数据量大 在js中&#xff0c;json是以对象的形式存在的&#x…...

26 用lsqnonlin求解最小二乘问题(matlab程序)

1.简述 函数语法 x lsqnonlin(fun,x0) 函数用于&#xff1a; 解决非线性最小二乘(非线性数据拟合)问题 解决非线性最小二乘曲线拟合问题的形式 变量x的约束上下限为ub和lb&#xff0c; x lsqnonlin(fun,x0)从x0点开始&#xff0c;找到fun中描述的函数的最小平方和。函数fu…...

Verilog语法学习——LV6_多功能数据处理器

LV6_多功能数据处理器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 根据指示信号select的不同&#xff0c;对输入信号a,b实现不同的运算。输入信号a…...

发送信息----策略模式

发送信息----策略模式 发送信息 发送信息 发送信息到手机、邮箱等&#xff0c;可扩展 package mainimport ("errors""fmt" )type PushContext struct {Phone, Email, Message stringTage int }type PaymentStrategy interface {Push(*P…...

PySpark介绍与安装

Spark是什么 定义&#xff1a;Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎。 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...