frp内网穿透配置
tags: 软件配置/frp 内网穿透 反向代理1. 介绍1.1 frp 是什么?frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 1.2 为什么使用 frp?通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括: 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。 代理组间的负载均衡。 端口复用,多个服务通过同一个服务端端口暴露。 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。 服务端和客户端 UI 页面。 2. 安装可以使用系统的包管理工具一键安装。如:scoop 、apt 、brew 等工具,比较简单。由于手动安装实用性更强,因此以下以...
关于Synchronized的一些讨论
本文主要目的是以synchronized为切入点来讨论相关的一些知识点。如下: synchronized介绍 synchronized锁升级 1. synchronized1.1 synchronized的作用synchronized通过使用互斥锁来锁定共享资源,使得同一时刻,只有一个线程可以访问和修改它,其他线程必须等待,当前线程修改完毕,释放互斥锁后,其他线程才能访问。其作用总结如下: 原子性:确保线程互斥的访问同步代码; 可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的 “对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在其他线程使用此变量前,需要重新从主内存中load” 来保证的; 有序性:有效解决重排序问题,即 “一个unlock操作先行发生于后面对同一个锁的lock操作”。 注意:这里的有序性是由于synchronized保证了原子性和可见性,在同一时刻只有一个线程可以执行同步代码块,而指令重排序在单线程的情况下,无论如何重排执行结果都不能被改变。因此,当以其他线程...
关于双亲委派
tags: - JVM - Javadate: 2024-04-15要了解双亲委派,就需要先了解类加载器,可以参考[[类的生命周期及类加载器]]一文。 1. 双亲委派机制是什么?双亲委派机制指的是:当一个类加载器收到加载类的任务时,会向上查找查找是否加载过,再由顶向下进行加载。 即,当某个类加载器收到加载任务,如果自己没有加载过此类,则会向上委派加载任务给自己的父加载器,如此重复知道委托到启动类加载器,然后再尝试加载类,如果当前类加载器无法加载,则任务下发给自己的子类加载器。过程如下图: 举例说明假设现在用应用程序类加载器(Application ClassLoader)来加载当前项目classpath目录下的 Demo9.class文件。步骤如下: Application ClassLoader收到加载任务后,先查询自己是否加载过此类。若加载过,直接返回class对象即可。否则委托给Extension/Platform ClassLoader。 Extension/Platform ClassLoader收到后,查询是否加载过此类,若加载过,直接返...
分享自用Halo网站自助定时备份方案
本站为Halo2搭建,Halo2默认使用的是H2数据库。为了防止意外数据丢失,需要做定时备份。现有增加备份的插件,但是需要付费。因此本文来介绍一个自助的定时备份方案。 1. 配置git12345yum install -y gitgit config --global user.name 'Git用户名'git config --global user.email "Git邮箱" 脚本提交的时候不输密码,所以需要配置ssh key,git远程仓库提供商的 ssh key配置验证方式不同。本文使用的是Gitee,可以查看其文档。 2. 初始化git仓库12345cd ~/.halo2git initgit remote add origin git@gitee.com:***/***.git 3. 编写自动备份脚本 blog_backup.sh: 12345678910111213141516171819202122232425#! /bin/bash# Print current timeecho "**********...
安装oh my zsh
tags: 软件配置/linux 软件配置/oh-my-zsh 软件配置/zsh1. 安装zsh本教程的为Ubuntu下操作。 1234567891011#安装zshsudo apt install zsh# 输出本机echo $SHELL # 修改本机默认shell (交互式修改)chsh # 修改默认Shell为zshchsh -s /bin/zsh 2 . 安装oh-my-zsh12345# giteesh -c "$(curl -fsSL https://gitee.com/shmhlsy/oh-my-zsh-install.sh/raw/master/install.sh)" # githubsh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"**** 如果使用官方的github源,速度可能有点慢。因此可以使用改造过的gitee源,若失效,百度即可。 3. 相关文件 配置文件位...
常见的垃圾回收器
本文主要内容是介绍常见的垃圾回收器。总体分为年轻代回收器和老年代类回收器,如下图所示: 可见,除了G1回收器外,年轻代和老年代回收器各三个。接下来将分别介绍。 1. Serial + Serial OldSerial和Serial Old是最古老的垃圾回收器。其特点是单线程执行,且在工作时,需要暂停其它所有的线程。它的优势是简单且高效,额外内存消耗小。目前是HotSpot虚拟机运行在客户端模式下的默认新生代和老年代垃圾回收器。有如下特点: 针对新生代; 采用复制算法; 单线程收集; 进行垃圾收集时,必须暂停所有工作线程,直到完成; 年轻代采用复制算法实现,老年代采用标记-整理算法实现。 1.1 优势简单高效,由于采用的是单线程的方法,因此与其他类型的收集器相比,对单个cpu来说没有了上下文之间的的切换,效率比较高。 1.2 劣势会在用户不知道的情况下停止所有工作线程。 1.3 使用场景 Client 模式(桌面应用): 在用户的桌面应用场景中,可用内存一般不大,可以在较短时间内完成垃圾收集,只要不频繁发生,这是可以接受的 单核服务器:对于限定单个CPU的环境来说...
类的生命周期及类加载器
1. 类的生命周期类的生命周期整体为:加载、连接、初始化、使用、卸载。其中连接阶段分为:验证、准备、解析。如下图所示: 1.1 加载阶段 首先,[[#2. 类加载器|类加载器]]根据类的全限定名通过不同的渠道(从磁盘、网络等)以二进制流的方式获取字节码信息; 然后JVM将字节码中的信息保存到内存的方法区中。在方法区生成一个InstanceKlass对象,保存类的所有信息; 并且在堆中保存一份与方法区中类似的java.lang.Class对象,用于在Java代码中获取类信息。 1.2 连接阶段如上图所示,连接阶段包含验证、准备、解析三个阶段。 1.2.1 验证这个阶段主要目的是检测字节码文件是否遵循《Java虚拟机规范》中的约束。主要包含一下几点: 文件格式验证,如:魔数的验证,注册版本号是否满足当前虚拟机的要求等; 元信息验证,如:所有类必须有父类,即super不能为空; 验证程序执行指令的语义; 符号引用验证,如:是否访问其他类中的private方法等。 1.2.2 准备一般情况下,此阶段将会为静态变量分配内存并设置初值。当静态变量为final修饰的话,准备阶段将直接按...
扫盲——脏读、不可重复读、幻读
MySQL的InnoDB存储引擎是支持多个事物并发执行的,这虽然提高了性能,但同时也带来了一些并发的问题。具体来说就是:脏读、不可重复读、幻读。本文来解释这几种现象是什么意思。 1. 脏读脏读就是在事务A中可以读到未提交的事务B中的数据。这些数据由于是未提交的,那么也可能会回滚。因此事务A可能会读到一些不存在的数据,这就是脏读。 事务A 事务B 开始事务 开始事务 更新数据x 查询到未提交的x数据 回滚数据 2. 不可重复读不可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况。举个例子: 事务A 事务B 开始事务 开始事务 第一次查询数据x 修改数据x 提交事务 第二次查询数据x 这种情况下,就会出现在同一个事务内,多次查询同一条数据结果不一致的情况。 3. 幻读幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。例如:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,...
线程的状态
本文的主题是讨论线程的状态。主要为操作系统层面的线程状态以及JVM层面上的线程状态之间的联系。并对JVM线程不同状态间的转换的方式进行梳理。 1. 操作系统层面操作系统层面的线程状态有五种,分别是:New、Ready、Running、Waiting、Terminate。如下图所示: New: 仅是在语⾔层⾯创建了线程对象,还未与操作系统线程关联; Ready: 指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执⾏; Running: 指获取了 CPU 时间⽚运⾏中的状态。当 CPU 时间⽚⽤完,会从运⾏状态转换⾄可运⾏状态,会导致线程的上下⽂切换; Waiting: 如果调⽤了阻塞 API,如 BIO 读写⽂件,这时该线程实际不会⽤到 CPU,会导致线程上下⽂切换,进⼊Waiting状态,等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换⾄Ready状态,与Ready的区别是,对Waiting的线程来说只要它们⼀直不唤醒,调度器就⼀直不会考虑调度它们。 Terminate: 表示线程已经执行完毕,生命周期已经结束,不会转换为其他状态。 2. JVM层...
认识AQS
在并发编程中,AQS(AbstractQueuedSynchronizer)是一个非常重要的类,JUC中很多工具都是基于AQS进行开发。其设计和编码思路都极其精妙。本文的目的是先对AQS进行一个大致的介绍,具体的实现细节将在后续的各种同步组件的实现中进行详细解释以体现出其设计思想的巧妙之处。 1. 动手实现一个锁为了认识AQS的功能,我们先自己动手实现一个非常简易的独占不可重入锁。代码如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051public class MyLock1 extends AbstractMyLock{ // 用于保存锁状态, 1表示有线程池有所,2表示锁空闲 private volatile int status; // 表示当前持有锁的线程 private volatile static Thread t = null; // Unsafe类的对象 private sta...