单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式也是开发过程中使用的最多的一种设计模式,它只允许创建一个对象,因此节省内存,加快了对象访问速度,当对象需要被公用的场景就很适合使用单例模式;但是它不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态
需要注意的是:
单例类只能有一个实例
单例类必须自己创建自己的唯一实例
单例类必须给所有其他对象提供这一实例
懒汉模式顾名思义就是特别懒,在类加载时不初始化,等到第一次被使用时才初始化。
public class Singleton{ // 创建示例,注意此时没有new private static volatile Singleton instance; // 构造方法私有化,无法在外部创建 ...
策略模式
为什么讲策略模式策略模式,应该是工作中比较常用的设计模式,调用方自己选择用哪一种策略完成对数据的操作,也就是“一个类的行为或其算法可以在运行时更改”我个人的理解是 将一些除了过程不同其他都一样的函数封装成策略,然后调用方自己去选择想让数据执行什么过程策略。常见的例子为根据用户分类推荐不同的排行榜(用户关注点不一样,推荐榜单就不一样)和单例模式一样,随着时间发展,我不再推荐经典策略模式,更推荐简单策略用枚举策略模式,复杂地用工厂策略模式。下面引入一个例子,我们的需求是:对一份股票数据列表,给出低价榜、高价榜、涨幅榜。这其中只有排序条件的区别,比较适合作为策略模式的例子
经典策略模式数据DTO
@Data public class Stock { // 股票交易代码 private String code; // 现价 private Double price; // 涨幅 private Double rise; }
抽象得到的策略接口
public interface Strategy ...
在oracle里杀死进程
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired错误
表示在尝试执行 SQL 语句时,目标资源正被其他会话占用,而由于 NOWAIT 或超时设置,当前操作未能成功获取锁。
目标表正被锁定
可能其他事务正在访问或修改 MYBOOT.PUS_MACHINE_MATERIAL_MESSAGE 表,导致无法获取锁。
解决方式
SELECT s.sid, s.serial#, s.username, s.program, o.object_name, l.locked_modeFROM v$locked_object lJOIN dba_objects o ON l.object_id = o.object_idJOIN v$session s ON l.session_id = s.sidWHERE o.object_name = 'PUS_MACHINE_MATERIAL_MESSAGE';
找到阻塞的会话 ...
mybatisPlus关联查询分页插件的坑
背景mybatis-plus自带一个分页插件,能够帮助我们快速的完成分页,详细用法可以看官网。但是分页插件只适用于基础的单表,对于需要聚合查询的一对多情况,有个很深的坑。
正确示例示例1使用子查询的方式,查询子实体,再collection标签里指定子查询语句select和关联的字段column
这个column也可以理解为子查询语句所需的参数,需要把主查询的哪个字段作为参数传入到子查询的查询方法里
// 实体类@Datapublic class NcsErBxzbDTO { // 主键 private String pkJkbx; // 单据编号 private String djbh; // 单据日期 private String djrq; // 单据总金额 private BigDecimal total; // 事由 private String zy; // 借款保险部门主键 private String deptId; // 借款报销部门名称 private String dept ...
接口定义常量的方式
常见的在java下定义常量的方式有静态变量或者枚举。今天看到别人的代码,还有用接口来定义常量的,分享一下。
静态常量
public class Constants { public static final String APP_NAME = "MyApplication"; public static final int MAX_USERS = 100; public static final double PI = 3.14159;}
枚举定义常量
public enum Status { SUCCESS, FAILURE, PENDING}
接口定义常量
public class NcConstant { public interface PROJECT_CLASS { // 销售类型的项目 String SALES_TYPE = "a"; } /** * 组织编码 */ ...
@JsonFormat和@DateTimeFormat
@JsonFormat 注解@JsonFormat 注解来自于 Jackson 库,通常用于控制日期时间格式在序列化和反序列化时的表现,主要应用于将Java对象转换为JSON时的日期时间格式处理,或者从JSON转换回Java对象时解析日期格式。
用法示例import com.fasterxml.jackson.annotation.JsonFormat;@Datapublic class Event { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date date1; @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private LocalDate date2; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = &quo ...
SpringBoot下的反射
普通的java反射调用一个方法的例子如下
import java.lang.reflect.Method;public class ReflectionExample { public static void main(String[] args) { try { // 获取类的 Class 对象 Class<?> clazz = Class.forName("TestClass"); // 创建类的实例 Object instance = clazz.getDeclaredConstructor().newInstance(); // 获取方法 Method method = clazz.getMethod("sayHello", String.class); // 调用方法 method.invoke(ins ...
docker安装minio
项目调试需要本地搭建一个minio,记录一下docker命令
docker run -d -p 9000:9000 -p 9001:9001 \--net=els \--name minio \-e "MINIO_ROOT_USER=minio" \-e "MINIO_ROOT_PASSWORD=minio123" \-v /Users/zhangyuhan/Work/dev-env/minio/data:/data \-v /Users/zhangyuhan/Work/dev-env/minio/config:/root/.minio \minio/minio server /data --console-address ":9001" -address ":9000"
java:Path与Files类
jDK1.7引入了新的IO操作类,java.nio.file包下的Path接口和Files类。然而网上的好多教程仍然用着比较老旧的File类。这里整理一下新的用法。
创建文件和目录创建文件和目录非常简单。我们可以使用Files类的createFile()方法和createDirectory()方法来创建文件和目录
import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.io.IOException;public class CreateFileAndDirectory { public static void main(String[] args) throws IOException { //文件 Path pathToFile = Paths.get("example.txt"); //目录 Path pathToDir = Paths.get(" ...
java split()方法输出示例
在java里,split()方法如果只传入分割字符,那么会自动去除结尾的空字符串。
以前一直不知道,到底写了多少隐藏的bug,ヽ(゜ロ゜;)ノ
情况1String str = "6000,5000";String[] s = str.split(",");System.out.println(Arrays.toString(s));// [6000, 5000]System.out.println(s.length);// 2
情况2String str = "6000,5000";String[] s = str.split(",", -1);System.out.println(Arrays.toString(s));// [6000, 5000]System.out.println(s.length);// 2
情况3String str = "6000,";String[] s = str.split(",");System.out.println(Array ...
配置ssl证书示例
server { listen 443 ssl; #修改端口号增加ssl server_name xxxx.cn; # 该域名必须对应当前nginx所在的服务器(通过dns解析的ip和nginx服务器的公网ip相同) #server_name _; #ssl on; #注释或删除ssl on ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置 ssl_prefer_server_ciphers on; #指定PEM格式的证书文件 ssl_certificate xxxx.pem; #指定PEM格式的私钥文件 ssl_certificate_key xxxx.key; location / { proxy_set_head ...
docker安装redis
docker pull redis:7.2docker run \-p 6379:6379 \--name redis-7.2 \--restart=always \--network=els \-d redis:7.2
m1,docker安装rabbitmq
基本安装# 拉镜像docker pull rabbitmq:3-management# 运行容器。# 项目用到mqtt,所以额外开启了一个mqtt插件# 可以把--network去掉,或者自己建个自定义网络elsdocker run -d --name rabbitmq-3 --network els -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=123456 -e RABBITMQ_PLUGINS_ENABLE=rabbitmq_mqtt rabbitmq:3-management
开启延时插件首先下载并启动镜像
docker pull rabbitmq:3.10.6-managementdocker run -d \--name rabbitmq \-e RABBITMQ_DEFAULT_USER=admin \-e RABBITMQ_DEFAULT_PASS=admin \-p 15672:15672 -p 5672:5672 -p 25672:25672 ...
m1,docker安装mysql5.7
mysql5.7版本没有适合arm架构的docker镜像但是网上大佬说x86镜像的mysql5.7一样能在macbook m1上运行自己试验了,果然可以。整理一下
# 拉取镜像(--platform linux/x86_64一定要加,要不然会报错,提示搜不到适合arm架构的mysql:5.7镜像)docker pull --platform linux/x86_64 mysql:5.7# 建立目录mkdir /Users/zhangyuhan/Work/dev-env/mysql-5.7/logmkdir /Users/zhangyuhan/Work/dev-env/mysql-5.7/datamkdir /Users/zhangyuhan/Work/dev-env/mysql-5.7/conf# 建立配置文件vim /Users/zhangyuhan/Work/dev-env/mysql-5.7/conf/my.cnf# 归纳整理mysql:5.7的一些通用配置[client]default-character-set=utf8mb4[mysql]default-character- ...
docker安装nginx
# 拉取镜像# 本文章以1.24为例,读者可以自行替换为其他的版本,流程基本不变。docker pull nginx:1.24# 运行容器,该容器只为复制配置文件,后续会删除docker run -p80:80 --name nginx-1.24 -d nginx:1.24# 得到容器id:e6c27ac9bc13# 创建映射目录# 所有的映射目录根目录为/Users/zhangyuhan/Work/dev-env/nginx-1.24,可自行替换mkdir /Users/zhangyuhan/Work/dev-env/nginx-1.24cd /Users/zhangyuhan/Work/dev-env/nginx-1.24mkdir confmkdir htmlmkdir logs# 将容器内的nginx配置文件夹拷贝到conf文件下docker cp e6c27ac9bc13:/etc/nginx /Users/zhangyuhan/Work/dev-env/nginx-1.24/conf# 此时目录结构为conf/nginx/一堆配置文件,所以需要将所有的配置文件拷贝conf下 ...
elasticsearch通过docker在mackbook m1安装
主要目的:安装elasticsearch和kibana,解决kibana无法连接elasticsearch导致server is not ready yet的问题
建立docker网络els# 建立docker network create els# 查看:有name:els,成功docker network lsNETWORK ID NAME DRIVER SCOPE12f31e2d6df1 bridge bridge local4e3cc13000ef els bridge locale0cb50b3dee5 host host local18f13202e657 none null local
安装elasticsearch# 建立映射文件夹mkdir /Users/zhangyuhan/Work/dev-env/elasticsearch-7.16.2/configmkdir /Users/zhangyuhan/Work/dev-env/elasticsearch-7. ...
redis主从、哨兵、集群搭建
博客参考
引申:如何给redis主从、哨兵模式添加认证密码
注意:如果三台服务器已经启动了主从和哨兵,那么需要先在三台服务器上关闭所有的哨兵,再在三台服务器上关闭所有的主从
服务器关闭顺序要求:先关从节点(从节点之间不分顺序),再关主节点
如果不知道哪个是主节点,可以通过redis-cli进入redis控制台输入info replication查看主节点的ip
#查看redis服务和哨兵的进程命令:ps -ef|grep redis
redis服务的关闭命令如下:
./redis-cli shutdown
redis哨兵的关闭命令如下
kill -9 哨兵进程
配置认证密码在上面博客配置的基础上执行如下步骤:
三台服务器的redis.conf添加如下配置
requirepass "123456"masterauth "123456"
三台服务器sentinel.conf添加如下配置
# 在上面博客里已经配置了sentinel monitor mymaster 10.13.181.97 6379 2# 新增的配置,要求写在上面配置的 ...
redis哨兵模式在springboot下的配置
springboot连接单体的redis配置如下
spring: redis: database: 0 host: 127.0.0.1 port: 6379 password:
但是如果是redis哨兵模式,那么上述配置会报错,无法连接redis。
正确连接redis哨兵模式在springboot中的配置如下
# Redis连接信息spring: redis: database: 0 # Redis数据库索引(默认为0) password: # timeout: 5000 # Redis超时时间(单位:毫秒) sentinel: master: mymaster # Sentinel主节点名称 nodes: 192.168.10.11:26379,192.168.10.12:26379,192.168.10.13:26379 # Sentinel节点地址列表 # 注意端口是26379,即哨兵模式的端口,不是6379,redis服务的端口
公网nfs配置踩坑
背景最近需要迁移一个老的单体项目到私有云环境做集群,之前的上传文件都是直接存储在磁盘上,而且体积超大,而且项目架构又从单体过渡到多个实例集群。为了能够读取到之前的上传文件,采用nfs将原先服务器上存储文件的路径挂载到新的私有云环境的多个集群服务器上。网上有很多关于nfs的配置讲解,但是大多是局域网。我这里因为两个环境都是独立封闭,只通过堡垒机提供外部访问,因此需要配置公网的nfs,踩了不少坑。在这里总结一下相关经验。
安装nfs安装的过程实际上很简单。我参考的这篇博客Centos7 NFS服务的安装以及使用
唯一值得注意的是,私有云环境不能用yum,因此我是上传的多个rpm包来手动执行的安装,这里是参考的这篇博客nfs无网络条件rpm安装
如果需要nfs的整合rpm包的话,可以发邮件给我
配置配置这里是踩坑最多的地方,内网的环境下大可以关闭防火墙,而外网环境下不可能对外暴漏所有的端口,因此要搞明白nfs到底配置那些端口开放才能让客户端成功挂载。我这里也是和同事不断的查资料,并且试错最后才成功的。👏🏻👏🏻👏🏻👏🏻👏🏻👏🏻
服务端还要额外配置5个端口# 修改vim ...
mysqldump定时备份
创建脚本创建一个新的Shell脚本文件,比如backup_mysql.sh
#!/bin/bash# MySQL数据库连接信息DB_USER="your_username"DB_PASSWORD="your_password"DB_NAME="your_database"# 备份保存路径BACKUP_DIR="/path/to/backup/directory"# 创建备份文件名,格式为:数据库名_年月日时分秒.sqlBACKUP_FILE="$BACKUP_DIR/$DB_NAME_$(date +%Y%m%d%H%M%S).sql"# 使用mysqldump命令备份数据库mysqldump -u$DB_USER -p$DB_PASSWORD $DB_NAME > $BACKUP_FILE# 检查备份是否成功if [ $? -eq 0 ]; then echo "MySQL backup completed successfully. Backup saved t ...