JumpServer
笔记安装JumpServer官网一键安装 修改配置远程访问的端口12345678910# 进入到jp的配置文件目录cd /opt/jumpserver/config# 修改配置文件vim config.txt# 修改配置,对外提供服务端口, 如果与现有服务冲突请自行修改HTTP_PORT=8083 # 修改这个端口# 重新启动cd /opt/jumpserver-installer-v3.6.3./jmsctl.sh restart 修改系统管理员密码123456789# 进入Docker容器$ docker exec -it jms_core /bin/bash# 进入根目录,如果不是Docker,进入cd /opt/jumpserver/apps$ cd apps/$ python manage.py changepassword admin# 输入新的密码$ password Nginx反向代理Nginx反向代理 配置SSL12345678910111213# 先停止服务cd /opt/jumpserver-installer-v3.6.3./jmsctl.sh stop# 把证书移动到这个目录/opt/jumpserver/config/nginx/cert# 修改配置文件,域名和ssl证书的文职/opt/jumpserver/config/config.txt# 启动服务cd /opt/jumpserver-installer-v3.6.3./jmsctl.sh start 配置SSH超时时间默认的时间好像半个小时不操作了,就会自动断开,改成最大值
Linux
系统命令解压缩demo(文件夹) |——|1.txt(文件) 12345678# -r:递归地压缩目录,意味着 zip 命令会包含 demo 文件夹内的所有文件和子目录。# demo.zip:这是输出的压缩文件名。# demo:这是您要压缩的目录名。zip -r demo.zip demo# -o:强制覆盖现有的文件和文件夹,而不会询问用户。# demo.zip:这是您想要解压的 .zip 文件名。unzip -o demo.zip 查看前几行1ifconfig | head -n 100 安装中文123456789apt install language-pack-zh-hansvim /etc/default/localeLANG=zh_CN.UTF-8LANGUAGE=zh_CN:zh:en_US:en# 验证root@anthony:~# echo $LANGzh_CN.UTF-8 Update索引失效12345678910111213正在读取软件包列表... 完成E: 无法下载 http://mirror.rise.ph/ubuntu/dists/focal-updates/main/dep11/Components-amd64.yml.xz 文件尺寸不符(264288 != 264484)。您使用的镜像正在同步中? [IP: 43.226.6.79 80] Hashes of expected file: - Filesize:264484 [weak] - SHA256:ea09acc6bddd6a503a3812ba1d3a025e5515c5469dcad172c86e2bda6f203752 - SHA1:60863a9cc3181eb87007edcfc2de1ba6a0b81a5f [weak] - MD5Sum:80baa34a1b24d245341757fa51ebd29e [weak] Release file created at: Sat, 27 Feb 2021 08:09:39 +0000E: 部分索引文件下载失败。如果忽略它们,那将转而使用旧的索引文件。# 解决办法sudo rm -rf /var/lib/apt/lists/partial/sudo apt update 修改时区12345678910111213141516# 查询当前时间date -R# tzselect选择 4,9,1,1# ubuntu特有的,如果不是ubuntu 跳过这一步sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime# java设置时区在/etc/profile或~/.bashrc文件中设置环境变量TZexport TZ='Asia/Shanghai'source /etc/profile# ubuntu20.04sudo timedatectl set-timezone Asia/Shanghai 历史命令12# 历史命令history -3 sudo免密vim /etc/sudoers 123456789101112131415# Host alias specification# User alias specification# Cmnd alias specification# User privilege specificationroot ALL=(ALL:ALL) ALL# 加在这里会被覆盖掉anthony ALL=(ALL) NOPASSWD:ALL# Members of the admin group may gain root privileges%admin ALL=(ALL) ALL# 最好是加在最后anthony ALL=(ALL) NOPASSWD:ALL# Allow members of group sudo to execute any command%sudo ALL=(ALL:ALL) ALLanthony ALL=(ALL) NOPASSWD:ALL grep管道1cat hive-default.xml | grep hive.cli.print 系统升级123yum -y update(centos)apt-get update(ubuntu 软件包的列表 )sudo apt-get dist-upgrade (进入列新你系统和系统里安装的软件) ll文件大小按MB显示12ls -lhll -lh 查看系统版本1cat /etc/os-release 立即关机和重启12345# 现在立即关机shutdown -h now # 现在立即重启shutdown -r now 当前时间1data / date -R 目录占用空间1234567891011121314151617181920# 查看当前目录下一级子文件和子目录占用的磁盘容量du -lh --max-depth=1 /# 查看当前目录总共占的容量。而不单独列出各子项占用的容量du -sh# 使用lsof命令排查,可以查看到状态为deleted的文件# 可考虑kill掉程序,就会自动释放lsof |grep deleted--------------------------------------------------------------------------------COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAMEdbus-daem 456 dbus txt REG 253,1 441144 141672 /usr/bin/dbus-daemon (deleted)...node 11595 11733 root txt REG 253,1 29851602 1461079 /home/elk/kibana-5.5.1-linux-x86_64/node/bin/node (deleted)node 11595 11733 root 1w REG 253,1 11374904415 1059873 /home/elk/kibana-5.5.1-linux-x86_64/nohup.out (deleted)node 11595 11733 root 2w REG 253,1 11374904415 1059873 /home/elk/kibana-5.5.1-linux-x86_64/nohup.out (deleted)async_17 24113 24210 rabbitmq 1w REG 253,1 8556707104 659069 /var/log/rabbitmq/startup_log (deleted)async_18 24113 24211 rabbitmq 1w REG 253,1 8556707104 659069 /var/log/rabbitmq/startup_log (deleted)async_19 24113 24212 rabbitmq 1w REG 253,1 8556707104 659069 /var/log/rabbitmq/startup_log (deleted)async_20 24113 24213 rabbitmq 1w REG 253,1 8556707104 659069 /var/log/rabbitmq/startup_log (deleted) 文件传输1234567891011# 获取远程服务器上的文件scp -P 2222 [email protected]:/root/lnmp0.4.tar.gz /home/lnmp0.4.tar.gz# 获取远程服务器上的目录scp -P 2222 -r [email protected]:/root/lnmp0.4/ /home/lnmp0.4/# 将本地文件上传到服务器上scp -P 2222 /home/lnmp0.4.tar.gz* *[email protected]:/root/lnmp0.4.tar.gz# 将本地目录上传到服务器上scp -P 2222 -r /home/lnmp0.4/* *[email protected]:/root/lnmp0.4/ 修改主机名字123456789# 第一种方法sudo vim /etc/sysconfig/network# 编辑HOSTNAME=weekend100sudo hostname weenkend110# 第二种方法,需要重启vim /etc/hostname Ubuntu右上角网络图标消失并且上不了网12345678910sudo nmcli networking offsudo nmcli networking onsudo service network-manager stopsudo rm /var/lib/NetworkManager/NetworkManager.statesudo service network-manager startsudo gedit /etc/NetworkManager/NetworkManager.conf# 把false改成truesudo service network-manager restart Cockpit1Activate the web console with: systemctl enable --now cockpit.socke Cockpit介绍自己是一个Web端的系统管理工具,只用鼠标点点就能管理系统,事实上也确实如此,我实际使用来说,启动Cockpit服务之后,只需要鼠标点点点就能完成系统很多基础操作,比如查看系统信息,启动/停止服务,新增或者更改账户,系统更新,Web终端及查看网络流量等功能。 12345systemctl start cockpit.socket # 运行Cockpit服务systemctl enable –now cockpit.socket # 启动该服务,随系统启动一同启动systemctl status cockpit.socket 然后在另一台电脑上用浏览器登录 https://IP:9090 top12345top - 21:08:58 up 6:15, 4 users, load average: 0.01, 0.03, 0.05Tasks: 262 total, 1 running, 261 sleeping, 0 stopped, 0 zombie%Cpu(s): 0.0 us, 1.4 sy, 0.0 ni, 98.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stKiB Mem : 3861300 total, 1922280 free, 1029068 used, 909952 buff/cacheKiB Swap: 2097148 total, 2097148 free, 0 used. 2545024 avail Mem 第一行 程序名(top) 21:08:58(系统时间) up 6:15(运行时间) 4 users(登录用户数) load average(cpu 负载数,5分钟的平均负载,10分钟的平均负载,15分钟的平均负载) 第二行 task(总进程数) 1 running (运行数:1) 261 sleeping(睡眠树:1) stopped(停止数) zoimbie(僵尸数) 第三行 %cpu(cpu使用占比) us (用户) sy (系统) ni(优先级) id(空闲) wa(等待) hi(硬件) st(虚拟机) 第四行 kib Mem (物理内存 单位:K) free (空间,单位:k) userd(使用) cache(缓存硬盘内容大小) 第五行 交换区 第六行 进程ID 用户名 优先级(PR) 内存(VIRT RES SHR) 状态(S) cpu 内存 运行时间 命令 tree12345# 排除目录venv目录tree -I '*venv*'# 排除目录venv和venve2目录tree -I '*venv|venv2*' 配置环境变量配置Java环境变量123export JAVA_HOME=/home/anthony/soft/jdk1.8.0_19export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 配置Maven环境变量12export M2_HOME=/usr/local/software/apache-maven-3.6.1export PATH=${M2_HOME}/bin:$PATH 安装和卸载OpenJDK12345678910111213# 安装apt-get install -y openjdk-17-jdk# 卸载openJDKsudo apt-get remove openjdk*# 查看jdk可安装的版本yum -y list java*# 选择一个安装# 要选择 要带有-devel的安装,因为这个安装的是jdk,而那个不带-devel的安装完了其实是jreyum install -y java-1.8.0-openjdk-devel.x86_64# 查找安装路径which java 配置Scala12export SCALA_HOME=/usr/local/scala-2.13.4export PATH=$SCALA_HOME/bin:$PATH 固定ip配置完了,最好是重启下vmware和虚拟机,和禁用开启 win10上的vmare8网卡 vmare配置 电脑配置虚拟机配置 Centos配置12345678910vim /etc/sysconfig/network-scripts/ifcfg-eth0BOOTPROTO="static" #dhcp改为staticONBOOT="yes" #开机启用本配置IPADDR=10.14.2.50 #静态IPGATEWAY=10.14.2.11 #默认网关NETMASK=255.255.255.0 #子网掩码# 重启网卡,或者重启电脑service network restart Ubuntu配置vim /etc/netplan 编辑完之后执行netplan apply 123456789101112131415161718192021222324# Ubuntu桌面版本network: version: 2 renderer: NetworkManager ethernets: ens33: dhcp4: no optional: true addresses: [192.168.0.5/24] gateway4: 192.168.0.1 nameservers: addresses: [192.168.0.1,8.8.8.8]# Ubuntu服务器版本network: ethernets: ens33: dhcp4: true optional: true addresses: [192.168.0.6/24] gateway4: 192.168.0.1 nameservers: addresses: [192.168.0.1,8.8.8.8] version: 2 关闭IPV6Ubuntu关闭IPV6 123sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1sudo sysctl -w net.ipv6.conf.lo.disable_ipv6= 防火墙Centos防火墙12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849# 启动systemctl start firewalld# 查看状态systemctl status firewalld# 停止systemctl disable firewalld# 禁用systemctl stop firewalld# 开机启动防火墙systemctl enable firewalld.service# 查看防火墙是否开机启动systemctl is-enabled firewalld.service# 开机时禁用防火墙systemctl disable firewalld.service# 查看版本firewall-cmd --version# 显示状态firewall-cmd --state# 查看所有打开的端口firewall-cmd --zone=public --list-ports# 重新载入,更新防火墙规则firewall-cmd --reload# 查看区域信息firewall-cmd --get-active-zones# 拒绝所有包firewall-cmd --panic-on# 取消拒绝状态firewall-cmd --panic-off# 查看是否拒绝firewall-cmd --query-panic# 开启80端口,–permanent永久生效,没有此参数重启后失效firewall-cmd --zone=public --add-port=80/tcp --permanent# 查看80端口是否开放firewall-cmd --zone=public --query-port=80/tcp# 删除80端口配置firewall-cmd --zone=public --remove-port=80/tcp --permanent Ubuntu防火墙12345678910# 开放端口sudo ufw allow 80# 查看所有的服务端口netstat -ap# 查看已经连接的服务端口netstat -a# 如查看8888端口,则在终端中输入:lsof -i:8888# lsof -i:端口号查看某个端口是否被占用netstat -anp|grep 80 转发IP12345678910111213141516171819# 在文件中添加或修改以下行sudo vim /etc/sysctl.confnet.ipv4.ip_forward=1# 激活 IP 转发功能。sudo sysctl -p# 182.160.10.16 目标到目标服务器的ip# 将到达端口 80 的流量转发到另一台服务器sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 182.160.10.16:80# 设置 MASQUERADE 以便正确处理返回的流量sudo iptables -t nat -A POSTROUTING -j MASQUERADE# 检查和保存规则sudo iptables -t nat -L -n -v# 如果您希望这些规则在系统重启后依然有效,您需要安装 iptables-persistent 包:sudo apt-get install iptables-persistent 用户和权限用户和用户组普通用户和非普通用户12$ 是普通用户# 不是普通用户 修改用户名12345678# //-l 新的登陆名称,-d 用户新的主目录, -m将家目录内容移至新位置 (仅于 -d 一起使用)usermod -l newname -d /home/newname -m oldname# 修改组groupmod -n oldname newname# 重启reboot 用户组123456789101112# 新建用户组groupadd hr# 查看用户组[root@192 ~]# tail -1 /etc/grouphr:x:1001:# 修改用户组名,sudan新名字,dan就名字groupmod -n susan dan# 删除用户组groupdel hr 用户12345678910111213141516171819202122232425262728293031323334# 添加用户:useradd hadoop,创建用户未指定任何选项,系统会创建一个同名的用户组# 添加用户adduser hadoop# 删除用户,# -r 同时也删除这个用户的主目录userdel -r hadoop# 修改hadoop用户密码passwd hadoop# 修改自己的用户名密码passwd# 把用户加入到用户组:vi /etc/sudoers# 查看用户id user01# 或者whoami# 或者cat /etc/shadow# 切换用户su anthony# 查看用户组信息[root@192 ~]# tail -2 /etc/passwdanthony:x:1000:1000:anthony:/home/anthony:/bin/bash[root@192 ~]# tail /etc/groupanthony:x:1000:anthony# 修改用户基本组usermod username -g 组名 修改用户基本组和附加组的demo1234567891011121314151617181920212223242526272829303132333435363738394041424344454647# 创建hadoop用户[root@192 ~]# useradd hadoop# 查看hadoop用户,基本组是1002[root@192 ~]# tail -1 /etc/passwdhadoop:x:1001:1002::/home/hadoop:/bin/bash# 查看hadoop基本组信息[root@192 ~]# tail -1 /etc/grouphadoop:x:1002:# 创建两个用户组[root@192 ~]# groupadd hadoop_base[root@192 ~]# groupadd hadoop_more# 查看两个用户组[root@192 ~]# tail -3 /etc/grouphadoop:x:1002:hadoop_base:x:1003:hadoop_more:x:1004:# 修改用户基本组[root@192 ~]# usermod hadoop -g hadoop_base[root@192 ~]# tail -3 /etc/grouphadoop:x:1002:hadoop_base:x:1003:hadoop_more:x:1004:# 用户的基本组已经变成1003[root@192 ~]# tail -3 /etc/passwdhadoop:x:1001:1003::/home/hadoop:/bin/bash# 修改用户附加组[root@192 ~]# usermod hadoop -G hadoop_more# 用户的附加组已经变成1004[root@192 ~]# tail -1 /etc/grouphadoop_more:x:1004:hadoop# 最后查看# uid 用户名# gid 基本组id# 组 包括基本组和附加组[root@192 ~]# id hadoopuid=1001(hadoop) gid=1003(hadoop_base) 组=1003(hadoop_base),1004(hadoop_more)# 从组中删除成员[root@192 ~]# gpasswd -d hadoop hadoop_base正在将用户“hadoop”从“hadoop_base”组中删除gpasswd:用户“hadoop”不是“hadoop_base”的成员[root@192 ~]# gpasswd -d hadoop hadoop_more正在将用户“hadoop”从“hadoop_more”组中删除 修改用户权限1root修改用户权限: vim /etc/sudousers 组信息文件123456[root@192 ~]# cat /etc/grouproot:x:0:bin:x:1:daemon:x:2:sys:x:3:adm:x:4: 一共有4列 组名 组密码 组ID 备用的 用户文件信息1234[root@192 ~]# cat /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologin 用户名,登录名中不能有冒号 口令,把真正的加密后的用户口令字存放到/etc/shadow文件中 用户标识符,取值范围是0-65535。0是超级用户root的标识号,1-99由系统保留,作为管理账号,普通用户的标识号从100开始。在Linux系统中,这个界限是500, 组标识符,也是基本组 注释性描述,例如用户的真实姓名、电话、地址等,这个字段并没有什么实际的用途 主目录 登录shell,解释器 权限123[anthony@192 ~]$ touch /tmp/demo.txt[anthony@192 ~]$ ll /tmp/demo.txt-rw-rw-r--. 1 anthony anthony 0 1月 11 21:57 /tmp/demo.txt 第一位 代表文件,d代表文件夹 接下来的三位(rw-),是用户权限 接下来的三位(rw-),是组权限 接下来的三位(r–),是其他人权限 . 不知道是啥东西 第二位,连接 第三位,属主 第四位,属组 第五位,大小 第六位,7位,时间 第八位,名字 提升权限12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061[root@192 tmp]# touch fil1.txt[root@192 tmp]# ll-rw-r--r--. 1 root root 0 1月 12 21:56 fil1.txt# 给所有人和用户都设置读写执行的权限[root@192 tmp]# chmod a=rwx fil1.txt[root@192 tmp]# ll-rwxrwxrwx. 1 root root 0 1月 12 21:56 fil1.txt# 给所有人和用户设置读写权限[root@192 tmp]# chmod a=rx fil1.txt[root@192 tmp]# ll-r-xr-xr-x. 1 root root 0 1月 12 21:56 fil1.txt# 给属主设置读权限[root@192 tmp]# chmod u=r fil1.txt[root@192 tmp]# ll-r--r-xr-x. 1 root root 0 1月 12 21:56 fil1.txt# 给组设置读写执行的权限[root@192 tmp]# chmod g=rwx fil1.txt[root@192 tmp]# ll-r--rwxr-x. 1 root root 0 1月 12 21:56 fil1.txt[root@192 tmp]## 给其他人 没有读写执行的权限[root@192 tmp]# chmod o= fil1.txt[root@192 tmp]# ll-r--rwx---. 1 root root 0 1月 12 21:56 fil1.txt# 给属主单独设置一个写的权限[root@192 tmp]# chmod u+w fil1.txt[root@192 tmp]# ll总用量 0-rw-rwx---. 1 root root 0 1月 12 21:56 fil1.txt# 修改文件的属主和组权限[root@192 tmp]# chown hadoop.hr fil1.txt[root@192 tmp]# ll总用量 0-rw-rwx---. 1 hadoop hr 0 1月 12 21:56 fil1.txt# 查看acl权限[root@192 tmp]# getfacl acldemo.txt# file: acldemo.txt# owner: root# group: rootuser::rw-group::r--other::r--# 当对一个文件或者文件夹需要设置3个以上的权限用户,和权限用户组,上面的那种方法就不够用了# 需要引入 acl权限# setfacl -m 对象:对象名:权限 文件名# ll之后就会先是+号setfacl -m g:hr:rw /tmp/acldemo.txt[root@192 tmp]# ll-rw-rw-r--+ 1 root root 0 1月 12 22:19 acldemo.txt 磁盘管理磁盘的三个步骤先分区,再格式化,再挂载 MBR一共只能有4个分区,如果要需要很多个分区 新建主分区和逻辑分区123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101[root@192 ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 20G 0 disk├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 19G 0 part ├─centos-root 253:0 0 17G 0 lvm / └─centos-swap 253:1 0 2G 0 lvm [SWAP]sdb 8:16 0 5G 0 disksdc 8:32 0 5G 0 disksdd 8:48 0 5G 0 disksde 8:64 0 5G 0 disksdf 8:80 0 5G 0 disksdg 8:96 0 5G 0 disksdh 8:112 0 5G 0 disksdi 8:128 0 5G 0 disksr0 11:0 1 4.4G 0 rom# 启动分区工具[root@192 ~]# fdisk /dev/sdb欢迎使用 fdisk (util-linux 2.23.2)。更改将停留在内存中,直到您决定将更改写入磁盘。使用写入命令前请三思。Device does not contain a recognized partition table使用磁盘标识符 0xda85d71c 创建新的 DOS 磁盘标签。命令(输入 m 获取帮助):nPartition type: p primary (0 primary, 0 extended, 4 free) e extendedSelect (default p): p分区号 (1-4,默认 1):起始 扇区 (2048-10485759,默认为 2048):+2GLast 扇区, +扇区 or +size{K,M,G} (4194304-10485759,默认为 10485759):将使用默认值 10485759分区 1 已设置为 Linux 类型,大小设为 3 GiB命令(输入 m 获取帮助):wThe partition table has been altered!Calling ioctl() to re-read partition table.正在同步磁盘。# 刷新分区[root@192 ~]# partprobe /dev/sdb# 查看分区结果[root@192 ~]# fdisk -l /dev/sdb磁盘 /dev/sdb:5368 MB, 5368709120 字节,10485760 个扇区Units = 扇区 of 1 * 512 = 512 bytes扇区大小(逻辑/物理):512 字节 / 512 字节I/O 大小(最小/最佳):512 字节 / 512 字节磁盘标签类型:dos磁盘标识符:0xda85d71c 设备 Boot Start End Blocks Id System/dev/sdb1 4194304 10485759 3145728 83 Linux# 格式化(创建文件系统)# ext4 扩展文件系统第四代,是文件系统的类型[root@192 ~]# mkfs.ext4 /dev/sdb1mke2fs 1.42.9 (28-Dec-2013)文件系统标签=OS type: Linux块大小=4096 (log=2)分块大小=4096 (log=2)Stride=0 blocks, Stripe width=0 blocks196608 inodes, 786432 blocks39321 blocks (5.00%) reserved for the super user第一个数据块=0Maximum filesystem blocks=80530636824 block groups32768 blocks per group, 32768 fragments per group8192 inodes per groupSuperblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912Allocating group tables: 完成正在写入inode表: 完成Creating journal (16384 blocks): 完成Writing superblocks and filesystem accounting information: 完成# 手动挂载[root@192 ~]# mkdir /mnt/disk1[root@192 mnt]# mount -t ext4 /dev/sdb1 /mnt/disk1/# 查看[root@192 mnt]# df -hT文件系统 类型 容量 已用 可用 已用% 挂载点devtmpfs devtmpfs 1.9G 0 1.9G 0% /devtmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmtmpfs tmpfs 1.9G 13M 1.9G 1% /runtmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/mapper/centos-root xfs 17G 4.4G 13G 26% //dev/sda1 xfs 1014M 239M 776M 24% /boottmpfs tmpfs 378M 12K 378M 1% /run/user/42tmpfs tmpfs 378M 0 378M 0% /run/user/0# 刚挂载的/dev/sdb1 ext4 2.9G 9.0M 2.8G 1% /mnt/disk1 新建SWAP123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148[root@localhost ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 20G 0 disk├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 19G 0 part ├─centos-root 253:0 0 17G 0 lvm / └─centos-swap 253:1 0 2G 0 lvm [SWAP]sdb 8:16 0 5G 0 disk└─sdb1 8:17 0 3G 0 part /mnt/disk1sdc 8:32 0 5G 0 disksdd 8:48 0 5G 0 disksde 8:64 0 5G 0 disksdf 8:80 0 5G 0 disksdg 8:96 0 5G 0 disksdh 8:112 0 5G 0 disksdi 8:128 0 5G 0 disksr0 11:0 1 4.4G 0 rom /run/media/anthony/CentOS 7 x86_64[root@localhost ~]# fdisk /dev/sdb欢迎使用 fdisk (util-linux 2.23.2)。更改将停留在内存中,直到您决定将更改写入磁盘。使用写入命令前请三思。命令(输入 m 获取帮助):nPartition type: p primary (2 primary, 0 extended, 2 free) e extendedSelect (default p): p分区号 (3,4,默认 3):No free sectors available命令(输入 m 获取帮助):q[root@localhost ~]# fdisk /dev/sdc欢迎使用 fdisk (util-linux 2.23.2)。更改将停留在内存中,直到您决定将更改写入磁盘。使用写入命令前请三思。Device does not contain a recognized partition table使用磁盘标识符 0x661ba46a 创建新的 DOS 磁盘标签。命令(输入 m 获取帮助):nPartition type: p primary (0 primary, 0 extended, 4 free) e extendedSelect (default p): p分区号 (1-4,默认 1):起始 扇区 (2048-10485759,默认为 2048):将使用默认值 2048Last 扇区, +扇区 or +size{K,M,G} (2048-10485759,默认为 10485759):将使用默认值 10485759分区 1 已设置为 Linux 类型,大小设为 5 GiB命令(输入 m 获取帮助):p磁盘 /dev/sdc:5368 MB, 5368709120 字节,10485760 个扇区Units = 扇区 of 1 * 512 = 512 bytes扇区大小(逻辑/物理):512 字节 / 512 字节I/O 大小(最小/最佳):512 字节 / 512 字节磁盘标签类型:dos磁盘标识符:0x661ba46a 设备 Boot Start End Blocks Id System/dev/sdc1 2048 10485759 5241856 83 Linux命令(输入 m 获取帮助):wThe partition table has been altered!Calling ioctl() to re-read partition table.正在同步磁盘。[root@localhost ~]# partprobe /dev/sdc[root@localhost ~]# fdisk -l /dev/sdb磁盘 /dev/sdb:5368 MB, 5368709120 字节,10485760 个扇区Units = 扇区 of 1 * 512 = 512 bytes扇区大小(逻辑/物理):512 字节 / 512 字节I/O 大小(最小/最佳):512 字节 / 512 字节磁盘标签类型:dos磁盘标识符:0xda85d71c 设备 Boot Start End Blocks Id System/dev/sdb1 4194304 10485759 3145728 83 Linux/dev/sdb2 2048 4194303 2096128 83 LinuxPartition table entries are not in disk order[root@localhost ~]# mkswap /dev/sdb2/dev/sdb2: 没有那个文件或目录[root@localhost ~]# mkswap /dev/sdc2/dev/sdc2: 没有那个文件或目录[root@localhost ~]# fdisk -l /dev/sdc磁盘 /dev/sdc:5368 MB, 5368709120 字节,10485760 个扇区Units = 扇区 of 1 * 512 = 512 bytes扇区大小(逻辑/物理):512 字节 / 512 字节I/O 大小(最小/最佳):512 字节 / 512 字节磁盘标签类型:dos磁盘标识符:0x661ba46a 设备 Boot Start End Blocks Id System/dev/sdc1 2048 10485759 5241856 83 Linux[root@localhost ~]# mkswap /dev/sdc1anaconda-ks.cfg .bashrc .dbus/ .local/ 模板/ 下载/.bash_history .cache/ .esd_auth .tcshrc 视频/ 音乐/.bash_logout .config/ .ICEauthority .viminfo 图片/ 桌面/.bash_profile .cshrc initial-setup-ks.cfg 公共/ 文档/[root@localhost ~]# mkswap /dev/sdc1正在设置交换空间版本 1,大小 = 5241852 KiB无标签,UUID=074198c5-dff9-4834-9fbb-06cee839372d[root@localhost ~]# df -hT文件系统 类型 容量 已用 可用 已用% 挂载点devtmpfs devtmpfs 1.9G 0 1.9G 0% /devtmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmtmpfs tmpfs 1.9G 13M 1.9G 1% /runtmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/mapper/centos-root xfs 17G 4.4G 13G 26% //dev/sda1 xfs 1014M 239M 776M 24% /boot/dev/sdb1 ext4 2.9G 9.0M 2.8G 1% /mnt/disk1tmpfs tmpfs 378M 32K 378M 1% /run/user/1000/dev/sr0 iso9660 4.4G 4.4G 0 100% /run/media/anthony/CentOS 7 x86_64tmpfs tmpfs 378M 0 378M 0% /run/user/0[root@localhost ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 20G 0 disk├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 19G 0 part ├─centos-root 253:0 0 17G 0 lvm / └─centos-swap 253:1 0 2G 0 lvm [SWAP]sdb 8:16 0 5G 0 disk└─sdb1 8:17 0 3G 0 part /mnt/disk1sdc 8:32 0 5G 0 disk└─sdc1 8:33 0 5G 0 partsdd 8:48 0 5G 0 disksde 8:64 0 5G 0 disksdf 8:80 0 5G 0 disksdg 8:96 0 5G 0 disksdh 8:112 0 5G 0 disksdi 8:128 0 5G 0 disksr0 11:0 1 4.4G 0 rom /run/media/anthony/CentOS 7 x86_64[root@localhost ~]# free -m total used free shared buff/cache availableMem: 3770 919 2208 26 642 2586Swap: 2047 0 2047[root@localhost ~]# swapon /dev/sdc1[root@localhost ~]# free -m total used free shared buff/cache availableMem: 3770 925 2201 26 642 2579Swap: 7166 0 7166 禁用swap12345678910一、不重启电脑,禁用启用swap,立刻生效# 禁用命令sudo swapoff -a# 启用命令sudo swapon -a# 查看交换分区的状态sudo free -m 创建LVM无限制的扩张容量 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120[root@192 ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 20G 0 disk├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 19G 0 part ├─centos-root 253:0 0 17G 0 lvm / └─centos-swap 253:1 0 2G 0 lvm [SWAP]sdb 8:16 0 5G 0 disk├─sdb1 8:17 0 3G 0 part└─sdb2 8:18 0 2G 0 partsdc 8:32 0 5G 0 disk└─sdc1 8:33 0 5G 0 part# 一会要操作的是这个盘sdd 8:48 0 5G 0 disksde 8:64 0 5G 0 disk# 一会要操作的是这个盘sdf 8:80 0 5G 0 disksdg 8:96 0 5G 0 disksdh 8:112 0 5G 0 disksdi 8:128 0 5G 0 disk# 物理磁盘转成物理卷[root@192 ~]# pvcreate /dev/sdd Physical volume "/dev/sdd" successfully created.# 创建数据卷组[root@192 ~]# vgcreate vg1 /dev/sdd Volume group "vg1" successfully created# 创建逻辑卷# lvcreate# -L 4g,要用磁盘的4G# -n lv1 卷的名字,自定义# vg1 卷组名,要把4G,加入到哪个卷组[root@192 ~]# lvcreate -L 4G -n lv1 vg1 Logical volume "lv1" created.# 格式化# 这里要用/dev/卷组名/逻辑卷的名字[root@192 ~]# mkfs.ext4 /dev/vg1/lv1mke2fs 1.42.9 (28-Dec-2013)文件系统标签=OS type: Linux块大小=4096 (log=2)分块大小=4096 (log=2)Stride=0 blocks, Stripe width=0 blocks262144 inodes, 1048576 blocks52428 blocks (5.00%) reserved for the super user第一个数据块=0Maximum filesystem blocks=107374182432 block groups32768 blocks per group, 32768 fragments per group8192 inodes per groupSuperblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736Allocating group tables: 完成正在写入inode表: 完成Creating journal (32768 blocks): 完成Writing superblocks and filesystem accounting information: 完成# 挂载,这里要用/dev/卷组名/逻辑卷的名字[root@192 ~]# mkdir /mnt/lv1[root@192 ~]# mount /dev/vg1/lv1 /mnt/lv1[root@192 ~]# df -hT文件系统 类型 容量 已用 可用 已用% 挂载点devtmpfs devtmpfs 1.9G 0 1.9G 0% /devtmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmtmpfs tmpfs 1.9G 13M 1.9G 1% /runtmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/mapper/centos-root xfs 17G 4.4G 13G 26% //dev/sda1 xfs 1014M 239M 776M 24% /boottmpfs tmpfs 378M 28K 378M 1% /run/user/1000/dev/sr0 iso9660 4.4G 4.4G 0 100% /run/media/anthony/CentOS 7 x86_64# 这里就有4个G的可用空间/dev/mapper/vg1-lv1 ext4 3.9G 16M 3.6G 1% /mnt/lv1# 把sdf物理磁盘转成物理卷[root@192 ~]# pvcreate /dev/sdf Physical volume "/dev/sdf" successfully created.[root@192 ~]# vgextend vg1 /dev/sdf Volume group "vg1" successfully extended# 扩容lv[root@192 ~]# lvextend -L +4G /dev/vg1/lv1 Size of logical volume vg1/lv1 changed from 4.00 GiB (1024 extents) to 8.00 GiB (2048 extents). Logical volume vg1/lv1 successfully resized.# 刷新[root@192 ~]# resize2fs /dev/vg1/lv1resize2fs 1.42.9 (28-Dec-2013)Filesystem at /dev/vg1/lv1 is mounted on /mnt/lv1; on-line resizing requiredold_desc_blocks = 1, new_desc_blocks = 1The filesystem on /dev/vg1/lv1 is now 2097152 blocks long.# 再次查看[root@192 ~]# df -hT文件系统 类型 容量 已用 可用 已用% 挂载点devtmpfs devtmpfs 1.9G 0 1.9G 0% /devtmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmtmpfs tmpfs 1.9G 13M 1.9G 1% /runtmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/mapper/centos-root xfs 17G 4.4G 13G 26% //dev/sda1 xfs 1014M 239M 776M 24% /boottmpfs tmpfs 378M 28K 378M 1% /run/user/1000# 这里就有8个G的可用空间/dev/mapper/vg1-lv1 ext4 7.8G 18M 7.4G 1% /mnt/lv1[root@192 ~]# pvs PV VG Fmt Attr PSize PFree /dev/sda2 centos lvm2 a-- <19.00g 0 /dev/sdd vg1 lvm2 a-- <5.00g 0 /dev/sdf vg1 lvm2 a-- <5.00g 1.99g[root@192 ~]# vgs VG #PV #LV #SN Attr VSize VFree centos 1 2 0 wz--n- <19.00g 0 vg1 2 1 0 wz--n- 9.99g 1.99g yumyum的所有文件都在/etc/yum.repos.d下 yum挂载光盘源新建一个xxx.repo的文件 12345[root@192 yum.repos.d]# cat ./dvd.repo[dvd]name=this is descreptionbaseurl=file:///mnt/cdromgpgcheck=0 挂载光盘 1234567891011121314151617181920212223[root@192 yum.repos.d]# df -hT文件系统 类型 容量 已用 可用 已用% 挂载点devtmpfs devtmpfs 1.9G 0 1.9G 0% /devtmpfs tmpfs 1.9G 0 1.9G 0% /dev/shmtmpfs tmpfs 1.9G 13M 1.9G 1% /runtmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup/dev/mapper/centos-root xfs 17G 4.4G 13G 26% //dev/sda1 xfs 1014M 239M 776M 24% /boottmpfs tmpfs 378M 32K 378M 1% /run/user/1000/dev/mapper/vg1-lv1 ext4 7.8G 18M 7.4G 1% /mnt/lv1/dev/sr0 iso9660 4.4G 4.4G 0 100%# 挂载mount /dev/sr0 /mnt/cdrom# 查看光盘你的包ls /mnt/cdrom/Packages/# 安装软件yum -y instal httpd# 安装rpm包rpm -ivh xxx.rpm
SpringBoot
定时器定时器的数值放到配置文件,如果使用@Scheduled(fixedDelay = 类中的变量)这种方式试过不行 123@Scheduled(fixedDelayString = "${fixedDelayString}")public void open() {} 1fixedDelayString=30000 RocketMQ下载源码或者二进制包 12345678# 源码安装# 解压文件unzip rocketmq-all-5.2.0-source-release.zipcd rocketmq-all-5.2.0-source-release/# 编译mvn -Prelease-all -DskipTests -Dspotbugs.skip=true clean install -U# 编译后的二进制的目录,配置文件在这里cd ./distribution 修改配置文件 1234567# 修改配置文件# 修改内存配置,虚拟机的内存太小了# vim ./bin/runserver.shJAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx521m -Xmn256g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"# vim ./bin/runbroker.shJAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m" 启动 123456# 第一步.启动Name Serversh bin/mqnamesrvThe Name Server boot success...# 第二步.启动Brokersh bin/mqbroker -n localhost:9876 The broker[%s, 172.30.30.233:10911] boot success... 测试发送消息 12345export NAMESRV_ADDR=localhost:9876# 发送消息sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer# 接收消息sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer 关闭服务12sh bin/mqshutdown brokersh bin/mqshutdown namesrv 监控1234567# 记得checkout release-rocketmq-console-1.0.0分支git clone https://github.com/apache/rocketmq-externals/tree/release-rocketmq-console-1.0.0# 修改配置文件里的rocketMQ远程地址NameSvrAddrList = 192.168.254.124:9876# 或者rocketmq.config.namesrvAddr=192.168.254.124:9876 代码单个生产者消费者12345678910111213141516171819202122232425262728293031public class Provider { public static void main(String[] args) throws Exception { DefaultMQProducer producer = new DefaultMQProducer("group1"); producer.setNamesrvAddr("192.168.254.190:9876"); producer.start(); String msg = "什么鬼,咋莫名其妙就收到了"; Message message = new Message("topic1", "tag1", msg.getBytes()); SendResult sendResult = producer.send(message); System.out.printf("%s%n", sendResult); producer.shutdown(); }}public class Consumer { public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1"); consumer.setNamesrvAddr("192.168.254.190:9876"); consumer.subscribe("topic1", "*"); consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }} 单个生产者多个消费者相同的Topic,相同的Group-负载均衡默认就是负载均衡,多个消费者,每个人收一条信息,不重复 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253public class Provider { public static void main(String[] args) throws Exception { DefaultMQProducer producer = new DefaultMQProducer("group2"); producer.setNamesrvAddr("192.168.254.190:9876"); producer.start(); for (int i = 0; i < 10; i++) { String msg = "默认接受者是负载均衡"+i; Message message = new Message("topic2", "tag1", msg.getBytes()); SendResult sendResult = producer.send(message); System.out.printf("%s%n", sendResult); } producer.shutdown(); }}public class Consumer { public static void main(String[] args) throws MQClientException { // 谁来收 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group2"); // 从哪里收 consumer.setNamesrvAddr("192.168.254.190:9876"); // 监听队列 consumer.subscribe("topic2", "*"); // 监听器 consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }}// 第一个消费者默认接受者是负载均衡0默认接受者是负载均衡1默认接受者是负载均衡4默认接受者是负载均衡5默认接受者是负载均衡8默认接受者是负载均衡9// 第二个消费者默认接受者是负载均衡2默认接受者是负载均衡3默认接受者是负载均衡6默认接受者是负载均衡7 相同的Topic,相同的Group-轮训只是添加了消费者的一段代码:consumer.setMessageModel(MessageModel.BROADCASTING); 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051public class Provider { public static void main(String[] args) throws Exception { // 谁来发 DefaultMQProducer producer = new DefaultMQProducer("group3"); // 发给谁 producer.setNamesrvAddr("192.168.254.190:9876"); producer.start(); for (int i = 0; i < 10; i++) { String msg = "默认接受者是负载均衡"+i; Message message = new Message("topic3", "tag1", msg.getBytes()); SendResult sendResult = producer.send(message); System.out.printf("%s%n", sendResult); } producer.shutdown(); }}public class Consumer { public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group3"); consumer.setNamesrvAddr("192.168.254.190:9876"); consumer.subscribe("topic3", "*"); consumer.setMessageModel(MessageModel.BROADCASTING); // 监听器 consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }}// 两个消费者都是收到相同的消息默认接受者是负载均衡0默认接受者是负载均衡1默认接受者是负载均衡2默认接受者是负载均衡3默认接受者是负载均衡4默认接受者是负载均衡5默认接受者是负载均衡6默认接受者是负载均衡7默认接受者是负载均衡8默认接受者是负载均衡9 不同的Topic,不同的Group 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788// 消费者1public class Consumer { public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group4"); consumer.setNamesrvAddr("192.168.254.190:9876"); consumer.subscribe("topic4", "*"); // 监听器 consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }}// 消费者2public class Consumer { public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group4"); consumer.setNamesrvAddr("192.168.254.190:9876"); consumer.subscribe("topic4", "*"); // 监听器 consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }}// 消费者3public class Consumer { public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group4-1"); consumer.setNamesrvAddr("192.168.254.190:9876"); consumer.subscribe("topic4", "*"); // 监听器 consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> { // 业务逻辑 list.forEach(one->{ byte[] body = one.getBody(); System.out.println(new String(body)); }); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumer.start(); System.out.println("消费者启起来了"); }}// 消费者1默认接受者是负载均衡2默认接受者是负载均衡3默认接受者是负载均衡6默认接受者是负载均衡7// 消费者2默认接受者是负载均衡0默认接受者是负载均衡1默认接受者是负载均衡4默认接受者是负载均衡5默认接受者是负载均衡8默认接受者是负载均衡9// 消费者3默认接受者是负载均衡0默认接受者是负载均衡1默认接受者是负载均衡2默认接受者是负载均衡3默认接受者是负载均衡4默认接受者是负载均衡5默认接受者是负载均衡6默认接受者是负载均衡7默认接受者是负载均衡8默认接受者是负载均衡9 Swagger123456<!-- 引入Swagger3依赖 --><dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version></dependency> 1234567891011121314151617181920212223242526272829303132333435363738import io.swagger.annotations.ApiOperation;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.oas.annotations.EnableOpenApi;import springfox.documentation.service.ApiInfo;import springfox.documentation.service.Contact;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;/** * Swagger配置类 */@EnableOpenApi@Configurationpublic class SwaggerConfig { @Bean public Docket docket(){ return new Docket(DocumentationType.OAS_30) .apiInfo(apiInfo()).enable(true) .select() //apis: 添加swagger接口提取范围 .apis(RequestHandlerSelectors.basePackage("com.example.study.controller")) .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("XX项目接口文档") .description("XX项目描述") .contact(new Contact("作者", "作者URL", "作者Email")) .version("1.0") .build(); }} 123# 原因是在springboot 2.6.0中将SpringMVC 默认路径匹配策略从AntPathMatcher# 更改为PathPatternParser,导致出错,解决办法是切换回原先的AntPathMatcherspring.mvc.pathmatch.matching-strategy=ant_path_matcher knife4j12345<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.3</version></dependency> application.properties 12spring.mvc.pathmatch.matching-strategy=ant_path_matcherknife4j.enable: true 12345678910111213141516171819@RestController@RequestMapping("/test")@Api(tags = "测试2")// 排序@ApiSort(value = 1)public class TestController2 { @GetMapping("/3") @ApiOperation("3") public String method(){ return "hello wolrd"; } @GetMapping("/4") @ApiOperation("4") public String method2(){ return "hello wolrd"; }} Log4j2Log4j2日志所有级别级别从上到下 ,级别从低到高,报错(更重要)这种,级别最高,info,debug相对不怎么重要 all trace debug info warn error fail Log4j2.xml配置例子 抄网上的示例实际开发用的1234info级别输出到info.logwarn级别输出warn.logerror级别输出到error.logdebug级别输出到debug.log 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164<?xml version="1.0" encoding="UTF-8"?><Configuration> <!--<Configuration status="WARN" monitorInterval="30"> --> <properties> <property name="LOG_HOME">./service-logs</property> </properties> <Appenders> <!--*********************控制台日志***********************--> <Console name="consoleAppender" target="SYSTEM_OUT"> <!--设置日志格式及颜色--> <PatternLayout pattern="%style{%d{ISO8601}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}" disableAnsi="false" noConsoleNoAnsi="false"/> </Console> <!--*********************文件日志***********************--> <!--all级别日志--> <RollingFile name="allFileAppender" fileName="${LOG_HOME}/all.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/all-%d{yyyy-MM-dd}-%i.log.gz"> <!--设置日志格式--> <PatternLayout> <pattern>%d %p %C{} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- 设置日志文件切分参数 --> <!--<OnStartupTriggeringPolicy/>--> <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新--> <SizeBasedTriggeringPolicy size="100 MB"/> <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置--> <TimeBasedTriggeringPolicy/> </Policies> <!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i--> <DefaultRolloverStrategy max="100"/> </RollingFile> <!--debug级别日志--> <RollingFile name="debugFileAppender" fileName="${LOG_HOME}/debug.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <!--过滤掉info及更高级别日志--> <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <!--设置日志格式--> <PatternLayout> <pattern>%d %p %C{} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- 设置日志文件切分参数 --> <!--<OnStartupTriggeringPolicy/>--> <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新--> <SizeBasedTriggeringPolicy size="100 MB"/> <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置--> <TimeBasedTriggeringPolicy/> </Policies> <!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i--> <DefaultRolloverStrategy max="100"/> </RollingFile> <!--info级别日志--> <RollingFile name="infoFileAppender" fileName="${LOG_HOME}/info.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <!--过滤掉warn及更高级别日志--> <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <!--设置日志格式--> <PatternLayout> <pattern>%d %p %C{} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- 设置日志文件切分参数 --> <!--<OnStartupTriggeringPolicy/>--> <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新--> <SizeBasedTriggeringPolicy size="100 MB"/> <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置--> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> <!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i--> <!--<DefaultRolloverStrategy max="100"/>--> </RollingFile> <!--warn级别日志--> <RollingFile name="warnFileAppender" fileName="${LOG_HOME}/warn.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <!--过滤掉error及更高级别日志--> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <!--设置日志格式--> <PatternLayout> <pattern>%d %p %C{} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- 设置日志文件切分参数 --> <!--<OnStartupTriggeringPolicy/>--> <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新--> <SizeBasedTriggeringPolicy size="100 MB"/> <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置--> <TimeBasedTriggeringPolicy/> </Policies> <!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i--> <DefaultRolloverStrategy max="100"/> </RollingFile> <!--error及更高级别日志--> <RollingFile name="errorFileAppender" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz"> <!--设置日志格式--> <PatternLayout> <pattern>%d %p %C{} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- 设置日志文件切分参数 --> <!--<OnStartupTriggeringPolicy/>--> <!--设置日志基础文件大小,超过该大小就触发日志文件滚动更新--> <SizeBasedTriggeringPolicy size="100 MB"/> <!--设置日志文件滚动更新的时间,依赖于文件命名filePattern的设置--> <TimeBasedTriggeringPolicy/> </Policies> <!--设置日志的文件个数上限,不设置默认为7个,超过大小后会被覆盖;依赖于filePattern中的%i--> <DefaultRolloverStrategy max="100"/> </RollingFile> <!--json格式error级别日志--> <RollingFile name="errorJsonAppender" fileName="${LOG_HOME}/error-json.log" filePattern="${LOG_HOME}/error-json-%d{yyyy-MM-dd}-%i.log.gz"> <JSONLayout compact="true" eventEol="true" locationInfo="true"/> <Policies> <SizeBasedTriggeringPolicy size="100 MB"/> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> </Policies> </RollingFile> </Appenders> <Loggers> <!-- 根日志设置 --> <Root level="debug"> <AppenderRef ref="allFileAppender" level="all"/> <AppenderRef ref="consoleAppender" level="debug"/> <AppenderRef ref="debugFileAppender" level="debug"/> <AppenderRef ref="infoFileAppender" level="info"/> <AppenderRef ref="warnFileAppender" level="warn"/> <AppenderRef ref="errorFileAppender" level="error"/> <AppenderRef ref="errorJsonAppender" level="error"/> </Root> <!--spring日志--> <Logger name="org.springframework" level="debug"/> <!--druid数据源日志--> <Logger name="druid.sql.Statement" level="warn"/> <!-- mybatis日志 --> <Logger name="com.mybatis" level="warn"/> <Logger name="org.hibernate" level="warn"/> <Logger name="com.zaxxer.hikari" level="info"/> <Logger name="org.quartz" level="info"/> <Logger name="com.andya.demo" level="debug"/> </Loggers></Configuration>123error级别 打印error.loginfo级别 打印info,error 日志到info.logdebug级别 打印info,error,debug日志到debug.log 基本结构是: Configuration properties 属性配置,可以在这里配置全局变量,可以在xml别的地方引入 Appenders 具体配置日志框架该如何收集日志的动作 Console 控制台输出 RollingFile 滚动日志文件 Loggers Root 理论上只有一个Root,level属性,是全局日志级别,如果AppenderRef没有配置level,就使用全局级别 AppenderRef 引用具体配置的动作,level 没有的话,就使用全局级别,就像CSS属性那样,标签里的属性优先级最高 Logger 单独配置一些类,level 没有的话,就使用全局级别,就像CSS属性那样,标签里的属性优先级最高 过滤器的具体使用方法 1234<Filters> <!--过滤掉info及更高级别日志--> <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/></Filters> level指定日志等级的阈值。 onMatch 定义当日志事件等级等于或高于 level 属性指定的等级时的行为。 ACCEPT:接受日志事件,让它通过过滤器。 DENY:拒绝日志事件,不让它通过过滤器。 NEUTRAL:对日志事件不做决定,继续应用其他的过滤规则。 onMismatch 定义当日志事件等级低于 level 属性指定的等级时的行为。 ACCEPT:接受日志事件,让它通过过滤器。 DENY:拒绝日志事件,不让它通过过滤器。 NEUTRAL:对日志事件不做决定,继续应用其他的过滤规则。 123456789if 日志的级别 >= level配置的级别 ACCEPT 接受日志 DENY 拒绝日志 NEUTRAL 对日志事件不做决定,继续应用其他的过滤规则if 日志的级别 < level配置的级别 ACCEPT 接受日志 DENY 拒绝日志 NEUTRAL 对日志事件不做决定,继续应用其他的过滤规则 还是没有搞清楚 onMismatch=”NEUTRAL” 的作用是怎样的 使用ChatGPT提供的demo,没有验证 info级别 记录到info.logerror级别 记录到error.loginfo级别和error级别 记录到dev.log 1234567891011121314151617181920212223242526272829<Configuration> <Appenders> <!-- Info 级别日志的 Appender --> <File name="InfoAppender" fileName="logs/info.log"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> </File> <!-- Error 级别日志的 Appender --> <File name="ErrorAppender" fileName="logs/error.log"> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> </File> <!-- 同时记录 Info 和 Error 级别日志的 Appender --> <File name="DevAppender" fileName="logs/dev.log"> <Filters> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> </File> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="InfoAppender"/> <AppenderRef ref="ErrorAppender"/> <AppenderRef ref="DevAppender"/> </Root> </Loggers></Configuration> 只是引入web框架只是引入web框架 1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency> 123456789101112@GetMapping("/test")public String test(){ // 格式化当前日期时间 String formattedDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); log.debug("当前日期时间:{}", formattedDateTime); log.info("当前日期时间:{}", formattedDateTime); log.error("当前日期时间:{}", formattedDateTime); log.warn("当前日期时间:{}", formattedDateTime); log.trace("当前日期时间:{}", formattedDateTime); return formattedDateTime;} 12345# 控制台打印INFO 64710 --- [nio-8080-exec-1] c.e.s.controller.IndexController : 当前日期时间:2024-03-03 21:37:40ERROR 64710 --- [nio-8080-exec-1] c.e.s.controller.IndexController : 当前日期时间:2024-03-03 21:37:40WARN 64710 --- [nio-8080-exec-1] c.e.s.controller.IndexController : 当前日期时间:2024-03-03 21:37:40# 为什么控制台没有打印 trace和debug日志
NodeJs
语法基本使用初始化项目 1npm init -y 创建文件 12# 新建src文件夹# 在src里新建index.html和index.css 安装jQuery 123# -S 的意思是 jquery安装好了,记录在package.json的 dependencies里# -S 等于 --save的简写npm i jquery -S index.html 12345678910111213141516171819202122<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <title>隔行变色</title> <script src="./index.js"></script> </head> <body> <ul> <li>这是第 1 个li</li> <li>这是第 2 个li</li> <li>这是第 3 个li</li> <li>这是第 4 个li</li> <li>这是第 5 个li</li> <li>这是第 6 个li</li> <li>这是第 7 个li</li> <li>这是第 8 个li</li> <li>这是第 9 个li</li> </ul> </body></html> index.js 1234567// 使用ES6的导入语法,导入jQueryimport $ from 'jquery'$(function(){ $("li:odd").css("background-color","red") $("li:even").css("background-color","pink")}) 运行index.html,就会报错,这时需要安装webpack 安装webpack ⛔ 安装webpack遇到的版本问题 要安装最新版本或特定版本,请运行以下命令之一: 123npm install --save-dev webpacknpm install --save-dev webpack@<version> 如果你使用 webpack 4+ 版本,你还需要安装 CLI。 1npm install --save-dev webpack-cli 1234567# 这个时候运行就会出问题# 需要安装webpack# @是指定版本# -D是指把版本信息记录到 devDepencies# devDepencies开发阶段会用到# -D 等于 --save-dev的简写npm insatll [email protected] [email protected] -D 创建webpack的配置文件webpack.config.js 123456789# 项目跟目录创建webpack配置文件,webpack.config.js# 使用Node.js的导出语法,向外导出一个webpack的配置对象modle.exports={ // 代表webpack的运行的模式, // 可选的值有两个 development 和 production mode : "development"} 修改package.json 1234# 在package.json的scripts节点下,新增dev脚本"scripts":{ "dev":"webpack"} 运行 12# 就会多了个dist的文件夹npm run dev 修改index.html的引入js路径 12# 修改index.html文件夹的scr导入路劲scr="./index.js" 改成 src="./dist/main.js" entry和output123456789101112const path = require("path")module.exports = { // 指定要最先处理的文件 entry:path.join(__dirname,"./src/index1.js"), // 指定生成的文件放在哪里 output:{ // 生成文件的目录 path:path.join(__dirname,"./dist2"), // 生成的文件名 filename:"bundle.js" }} 修改代码实时生效插件1npm install webpack-dev-server --save-dev 修改package.json 123"scripts": { "dev": "webpack serve"} 1npm i --save-dev html-webpack-plugin 修改webpack.config.json 12345678910111213const htmlplugin = require("html-webpack-plugin")plugin = new htmlplugin({ // 指定要服务的页面 template:"./src/index.html", // 复制到哪里去 filename:"./index.html"})module.exports = { mode:"development", plugins:[plugin]} 配置devServer12345678910module.exports = { mode:"development", plugins:[plugin], devServer:{ // 自动打开浏览器 open:true, // 端口 port:10086 }} loaderwebpack默认只处理js格式的文件,比如要处理CSS,需要安装 12npm install --save-dev css-loadernpm install --save-dev style-loader 在src下新建css文件夹,在css文件夹下新建一个index.css 在index.js导入css文件 12// 导入样式,在webpack中,所有的文件都可以用ES6语法导入import "./css/index.css" 配置webpack.config.js 12345678910111213// 先找到css-loader处理,再给style-loader处理module.exports = { mode:"development", module:{ // 所有第三方文件模块的匹配规则 rules:[ // 文件后缀的匹配规则 { test:/\.css$/,use:["style-loader","css-loader"] } ] }} less-loader在上面的css文件夹下,创建个index.less文件 12345678910// index.lesshtml,body,ul{ padding: 0; margin: 0; li{ line-height: 30px; padding-left: 20px; font-size: 12px; }} 12npm install less -Dnpm install less less-loader --save-dev 配置webpack.config.js 1234567891011121314module.exports = { mode:"development", module:{ // 所有第三方文件模块的匹配规则 rules:[ // 文件后缀的匹配规则 // 处理css {test:/\.css$/,use:["style-loader","css-loader"]}, // 处理less {test: /\.less$/, use: ["style-loader", "css-loader", "less-loader",], }, ] }} 图片loader没学 babel-loader没学 build打包优化自动清理dist目录下的旧文件1npm install --save-dev clean-webpack-plugin 12345678const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = { plugins:[plugin,new CleanWebpackPlugin()], output:{ path:path.join(__dirname,"./dist") }} Source Map一个信息文件,存储这位置信息,存储压缩混淆后的代码,所对应的转换钱的位置 123456module.exports = { mode:"development", // 生产的时候要关闭,也可以 设置 nosources-source-map // nosources-source-map 显示行号,不显示源码 devtool:"eval-source-map"} @的原理标识src源代码目录,从外往里找, 就可以不用使用../从里往外找 告诉webpack,@的目录 1234567module.exports = { resolve:{ alias:{ "@":path.join(__dirname,"./src/") } }} Eslint12345678910{ // 是否使用分号结尾 "semi": true, // 是否使用单引号 "singleQuote": false, // 最后一句话逗号结尾 "trailingComma": "none"} 在Vue项目的根目录中创建vue.config.js文件 12345678910# 在脚手架生成的代码添加module.exports = defineConfig({ # 要添加的代码 lintOnSave:false})# 或者module.exports = { lintOnSave:false} 入门应用1234567891011121314151617var http = require('http');http.createServer(function (request, response) { // 发送 HTTP 头部 // HTTP 状态值: 200 : OK // 内容类型: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // 发送响应数据 "Hello World" response.end('Hello World\n');}).listen(8888);// 终端打印如下信息console.log('Server running at http://127.0.0.1:8888/');// 运行node server.js Npm升级 1npm i -g npm to update Node.jsmac安装 1brew install nodejs npm更换版本 12# npm更换npm install [email protected] -g node.js更换版本 12345678910111213141516171819202122# node更换sudo npm install n -g# 安装指定版本号的nodejs,记得使用sudosudo n 14.16.0# 切换nodejs版本号n# 输入n之后,打印的数据ο node/14.16.0------------------------------------------# 使用nvm更换版本brew install nvm# 查看远程版本nvm ls-remote# 安装制定版本号nvm install v15.3.2# 已经安装的版本号nvm ls# 切换已经安装的版本号nvm use 4.2 依赖管理 123456789101112131415161718192021# 安装但不写入package.json;npm install xxx# 安装并写入package.json的"dependencies"中npm install xxx –S# 安装并写入package.json的"devDependencies"中npm install xxx –D# 全局安装npm install xxx -g# 安装指定版本npm install [email protected]# 更新包npm install -g npm-check-updates# 检查可更新的模块ncu# 来更新package.json的依赖包到最新版本ncu -u node.js升级 12345678910111213# 更新npmnpm install -g npm# 清空npm缓存npm cache clean -f# 安装n模块npm install -g n# 升级node.js到最新稳定版n stable# 有时候需要sudo权限,或者安装好了之后要开启一个新的shell才能用到新的版本 https://www.bilibili.com/video/BV1vE411871g?p=120 安装源 依赖升级 123npm install -g npm-upgrade # 先全局安装 npm-upgradenpm-upgrade # 当前项目下的包全都更新npm-upgrade <package> # 当前项目下的指定包更新 ES6 & JS字符串转数字 遍历2 排序 排序 join方法 遍历 1JavaScript for...in .. foreach 1row.typeID.split(",").forEach(id=>{this.gameTypes.push(parseInt(id))}) NodJs项目部署到Vercel1.创建node项目 1npm init 2.安装依赖,package.json 123456{ "dependencies": { "@vercel/node": "^2.15.3", "express": "^4.18.2" }} 3.创建vercel.json 123456789101112131415{ "version": 2, "builds": [ { "src": "app.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "app.js" } ]} 4.创建app.js 1234567891011const express = require('express')const app = express()const port = 3000app.get('/', (req, res) => { res.send('Hello World!')})app.listen(port, () => { console.log(`Example app listening on port ${port}`)}) 5.像平常部署别的项目一样,部署这个项目就可以,部署好之后,就能看到首页的Hello World!
SpringBoot配置Gmail
申请应用程序验证码 配置二步验证 要配置二步验证,才能看到应用程序的选项 最后就能获取到应用程序验证码 引入代码 1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency> application.properties文件配置 12345678910111213spring.mail.host=smtp.gmail.com# 邮件服务器端口号spring.mail.port=587# 邮件发送方的电子邮件地址spring.mail.username=你的Gmail邮箱账号# 邮件发送方的密码或应用程序专用密码一定要开启了两步验证spring.mail.password=应用程序专用密码# 启用TLS加密spring.mail.properties.mail.smtp.starttls.enable=true# 验证邮件服务器的身份spring.mail.properties.mail.smtp.auth=true# 邮件传输协议spring.mail.properties.mail.transport.protocol=smtp 配置的代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108@Servicepublic class EmailUtil implements EmailService{ private final Logger logger = LoggerFactory.getLogger(this.getClass()); //Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口,这里直接注入即可使用 @Autowired private JavaMailSender mailSender; // 配置文件中我的谷歌邮箱 @Value("${spring.mail.username}") private String from; /** * 简单文本邮件 * @param to 收件人 * @param subject 主题 * @param content 内容 */ @Override public void sendSimpleMail(String to, String subject, String content) { //创建SimpleMailMessage对象 SimpleMailMessage message = new SimpleMailMessage(); //邮件发送人 message.setFrom(from); //邮件接收人 message.setTo(to); //邮件主题 message.setSubject(subject); //邮件内容 message.setText(content); //发送邮件 mailSender.send(message); } /** * html邮件 * @param to 收件人,多个时参数形式 :"[email protected],[email protected],[email protected]" * @param subject 主题 * @param content 内容 */ @Override public void sendHtmlMail(String to, String subject, String content) { //获取MimeMessage对象 MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper messageHelper; try { messageHelper = new MimeMessageHelper(message, true); //邮件发送人 messageHelper.setFrom(from); //邮件接收人,设置多个收件人地址 InternetAddress[] internetAddressTo = InternetAddress.parse(to); messageHelper.setTo(internetAddressTo); //messageHelper.setTo(to); //邮件主题 message.setSubject(subject); //邮件内容,html格式 messageHelper.setText(content, true); //发送 mailSender.send(message); //日志信息 logger.info("邮件已经发送。"); } catch (Exception e) { logger.error("发送邮件时发生异常!", e); } } /** * 带附件的邮件 * @param to 收件人 * @param subject 主题 * @param content 内容 * @param filePath 附件 */ @Override public void sendAttachmentsMail(String to, String subject, String content, String filePath) { MimeMessage message = mailSender.createMimeMessage(); try { MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content, true); FileSystemResource file = new FileSystemResource(new File(filePath)); String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); helper.addAttachment(fileName, file); mailSender.send(message); //日志信息 logger.info("邮件已经发送。"); } catch (Exception e) { logger.error("发送邮件时发生异常!", e); } } /** * 验证邮箱格式 * @param email * @return */ public boolean isEmail(String email) { if (email == null || email.length() < 1 || email.length() > 256) { return false; } Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"); return pattern.matcher(email).matches(); }} 1234567891011121314151617181920212223242526272829public interface EmailService { /** * 发送文本邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容 */ void sendSimpleMail(String to, String subject, String content); /** * 发送HTML邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容 */ public void sendHtmlMail(String to, String subject, String content); /** * 发送带附件的邮件 * * @param to 收件人 * @param subject 主题 * @param content 内容 * @param filePath 附件 */ public void sendAttachmentsMail(String to, String subject, String content, String filePath);} 123456789101112131415161718192021222324@Servicepublic class CodeUtil { @Autowired private StringRedisTemplate redisTemplate; public String generateVerificationCode() { // 生成6位随机数字验证码 return String.valueOf((int) ((Math.random() * 9 + 1) * 100000)); } // 验证验证码是否正确 public boolean verifyCode(String userId, String code,String key) { key = key + userId; String storedCode = redisTemplate.opsForValue().get(key); return code.equals(storedCode); } //删除redis中验证码 public void deleteCode(String userId,String key) { key = key + userId; redisTemplate.delete(key); }} 1234567//写在需要发送验证码的地方//存储时间 private static final int EXPIRATION_TIME_IN_MINUTES = 3; //键名 private static final String KEY_PREFIX =="xxx"; key=KEY_PREFIX+"123456"redisTemplate.opsForValue().set(key, 随机数字验证码, EXPIRATION_TIME_IN_MINUTES, TimeUnit.MINUTES);
Vue后台系统
项目由 Vue3 + Pina + JavaScript + Ant Design Vue 创建项目12345# 直接创建npm create vite@latest my-vue-app -- --template vue# 如果要创建ts或者自定义配置的项目就用这个npm create vite 引入Ant Design Vue1npm i --save [email protected] mian.js 删掉自带的style.css文件 12345678import {createApp} from 'vue'import Antd from 'ant-design-vue';import 'ant-design-vue/dist/reset.css';import App from './App.vue'const app = createApp(App);app.use(Antd)app.mount('#app'); 安装router1npm install vue-router@4 创建src/router/index.js文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546import { createWebHistory, createRouter } from 'vue-router'/** * Note: 路由配置项 * * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 * name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题 * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 * roles: ['admin', 'common'] // 访问路由的角色权限 * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 * meta : { noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false) title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 } */// 公共路由export const constantRoutes = [ { path: '/login', component: () => import('@/views/login'), hidden: true },]const router = createRouter({ history: createWebHistory(), routes: constantRoutes, scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { top: 0 } } },});export default router; 配置开发环境编辑vite.config.js 123456789101112131415161718192021import { defineConfig, loadEnv } from 'vite'import path from 'path'import vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/export default defineConfig(({ mode, command }) => { return { plugins: [vue()], resolve: { // https://cn.vitejs.dev/config/#resolve-alias alias: { // 设置路径 '~': path.resolve(__dirname, './'), // 设置别名 '@': path.resolve(__dirname, './src') }, // https://cn.vitejs.dev/config/#resolve-extensions extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] } }}) 项目根目录创建环境配置文件 .env.development .env.prod 12345678# 页面标题VITE_APP_TITLE = 若依管理系统# 开发环境配置VITE_APP_ENV = 'development'# 若依管理系统/开发环境VITE_APP_BASE_API = '/dev-api' 安装sass12345npm install -D sass# 直接使用就可以<style lang="scss" scoped></style> 全局样式创建src/style/index.scss文件 123456789101112131415161718@import './demo.scss';html { height: 100vh; box-sizing: border-box;}body { height: 100vh; margin: 0; //-moz-osx-font-smoothing: grayscale; //-webkit-font-smoothing: antialiased; //text-rendering: optimizeLegibility; //font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;}#app { height: 100vh;} 创建src/style/demo.scss文件 1// 这个文件是用来写css的,前面导入的这个文件,所以后面只需要写就行了 导入scss,编辑main.js 1import './style/index.scss' Ant Design Vue Icon的使用123456789101112131415<template> <a-form class="login-from"> <a-form-item size> <a-input placeholder="请输入用户名" size="large"> <template #prefix> <UserOutlined/> </template> </a-input> </a-form-item> </a-form></template><script setup> import {UserOutlined, LockOutlined} from '@ant-design/icons-vue'</script> 安装Axios1npm install axios 创建 src/utils/request.js 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556import axios from 'axios'axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'// 创建axios实例const service = axios.create({ // axios中请求配置有baseURL选项,表示请求URL公共部分 baseURL: import.meta.env.VITE_APP_BASE_API, // 超时 timeout: 10000})// request拦截器service.interceptors.request.use(config => { return config}, error => { console.log(error) Promise.reject(error)})// 响应拦截器service.interceptors.response.use(res => { // 未设置状态码则默认成功状态 const code = res.data.code || 200; if (code === 401) { return Promise.reject('无效的会话,或者会话已过期,请重新登录。') } else if (code === 500) { ElMessage({ message: msg, type: 'error' }) return Promise.reject(new Error(msg)) } else if (code === 601) { ElMessage({ message: msg, type: 'warning' }) return Promise.reject(new Error(msg)) } else if (code !== 200) { ElNotification.error({ title: msg }) return Promise.reject('error') } else { return Promise.resolve(res.data) } }, error => { console.log('err' + error) let { message } = error; if (message == "Network Error") { message = "后端接口连接异常"; } else if (message.includes("timeout")) { message = "系统接口请求超时"; } else if (message.includes("Request failed with status code")) { message = "系统接口" + message.substr(message.length - 3) + "异常"; } ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) })export default service main.js 1import router from './router'
Mac
快捷键 描述 命令 一个应用多个窗口 切换 command+` 录屏幕 shift+command+5 截图 shift+command+4 重装系统 先一直按住不要松手:Common+R,再按开机键;非苹果键盘,按住微软键+R 上一级目录 command+↑ 网站链接 一招解决 Chrome / Edge 浏览器卡顿变慢视频掉帧问题 - 让浏览器重回丝般流畅 AltTab iphone强制重启 浏览器返回手势 放歌有噪音通过【活动监视器】程序终止【coreaudiod】进程: 聚焦搜索】中输入【activity monitor】 在窗口右上角的搜索栏里输入【coreaudiod】 选择【coreaudiod】进程后,点击窗口上方工具栏中的【停止按钮】(按钮图标为X) 只有mac不能访问github 打开https://github.com.ipaddress.com/ 打开https://fastly.net.ipaddress.com/github.global.ssl.fastly.net#ipinfo sudo vim /etc/hosts 1234# 这个ip从第一步获取到的140.82.112.4 github.com# 这个ip从第二步获取到的199.232.69.194 github.global.ssl.fastly.net 刷新:sudo killall -HUP mDNSResponder;say DNS cache has been flushed 启动台有问号的图标,点击没反应123# 执行了之后,自己新建的文件夹会重置defaults write com.apple.dock ResetLaunchPad -bool TRUEkillall Dock Mac OS X 访问 Windows共享文件夹 在Mac中,点击 Finder菜单的“前往” > “前往服务器”。在弹出的连接服务器对话框中输入「smb://Windows主机的IP地址」,点击“连接”。 一般需要输入Windows对应用户的名称和密码,然后弹出如下窗口,选择对应的文件夹,点击“好”即可进行远程访问 只使用搜狗输入法系统偏好设置 >> 键盘 >> 快捷键 >> 反选切换输入法的快捷键 网络踪迹1traceroute ap-southeast-1.signin.aws.amazon.com 安装mysql客户端1234567brew install mysql-client# 安装目录在/opt/homebrew/Cellar/mysql-client/8.0.33_1 # mysqldump的目录/opt/homebrew/opt/mysql-client/bin/mysqldump Iterm2Iterm2多窗口同时输入命令只需要输入快捷键 ⌘(command) + ⇧(shift) + i 调出复制过的文本历史快捷键:“shift+cmd+h” 按键回放回放一段时间内的你敲过的所有字符。快捷键:“cmd+alt+b”,如图会弹出一个进度条,按左右键就可以实现按键回放了。 CheatSheet1234brew install cheatsheet# 使用随便在一个软件中 长按`command` Navicat破解gitee脚本 mac安装 protobuf123brew install protobufprotoc --version/opt/homebrew/share/emacs/site-lisp/protobuf 视频格式转换12345brew install ffmpeg# 使用这个命令ffmpeg -i input.mov -c copy output.mp4 # 不要用这个命令,网上说是速度很慢ffmpeg -i input.mov output.mp4
虚拟机
VirtualBox增强功能Centos8123456789# 需要安装一定的依赖,例如:make gcc perlsudo yum install gcc perl make tar bzip2 elfutils-libelf-devel#同时安装的kernel-devel版本要和内核版本一致,安装对应版本sudo yum install -y "kernel-devel-uname-r == $(uname -r)"# 或者通过DNF安装所有:dnf install tar bzip2 kernel-devel-$(uname -r) kernel-headers perl gcc make elfutils-libelf-devel
