Mac Apple芯片安装Win11
Mac Apple芯片安装Win11 M1/M2 Pro VMware Fusion虚拟机安装Win11教程(超详细)_m1装win11_七维大脑的博客-CSDN博客 M用户使用VM虚拟机安装win11连不上网,怎么解决_mac_xwz的博客-CSDN博客 记得要下载ARM版本的 这里设置的密码,后面不会再用了,可以设置个简单点的就行 内存设置4GB,硬盘设置成80GB 这里要快速按回车,不然就提示EFI Network,如果是这个提示,重新启动虚拟机就行,之后就是正常安装Window系统的步骤,然后就会遇到连接到网络的问题 Shift + F10打开命令行,输入OOBE\BYPASSNRO 然后系统就行回重启,然后又回到设置Windown的设置开始,这是正常的,然后就一直都是配置,正常配置就好,选择没有连接,就可以创建本地账号 安装完成之后,是没有网络的,需要安装vm-tools 正常安装软件的步骤就可以了 固定IP配置完了,最好是重启下vmware和虚拟机,和禁用开启 win10上的vmare8网卡 1.vmare配置 2.电脑配置,虚拟机配置
ESM
导入和导出Es Module和CommonJs的导入导出不一样 1234567891011121314// b.js// 一个模块只能有一个默认输出,export default 命令只能使用一次;export default function sayHello() { console.log('Hello!');}export default function sayHello2() { console.log('Hello!');}// a.js , 运行报错import sayHello from './b.js';sayHello(); 如何导出多个变量呢 12345678910111213// b.jsexport function sayHello() { console.log('Hello!');}export function sayHello2() { console.log('Hello!');}// a.jsimport {sayHello} from './b.js';sayHello(); 什么时候花括号呢? 12345678910111213141516// b.js// 对于import命令后面不用加大括号,因为只有唯一对应export default命令。export default function sayHello() { console.log('Hello!');}export function sayHello2() { console.log('Hello2!');}// a.js// 导入default的变量不用花括号import sayHello, {sayHello2} from './b.js';sayHello();sayHello2(); Promise基本代码结构 12345678910111213141516171819202122232425const myPromise = new Promise((resolve, reject) => { // 异步操作 (如读取文件、获取数据) let success = true; // 这是模拟的异步操作结果 if (success) { resolve("操作成功!"); // 成功时调用 resolve } else { reject("操作失败!"); // 失败时调用 reject }});// 使用 .then() 处理成功的情况,使用 .catch() 处理失败的情况myPromise.then((result) => { console.log(result); // 输出:操作成功! }) .catch((error) => { console.log(error); // 如果失败,则输出错误信息 });// 也可以写成这样myPromise .then( () => { console.log("操作成功!"); }, // 成功时执行 () => { console.log("操作失败!"); } // 失败时执行 );
Flarum
Flarum 部署 Ubuntu 24.04 安装 PHP、MariaDB、Nginx、Composer 安装的目录是在/home/ubuntu/flarum/ 安装Flarum✅ 安装PHP12345678910111213141516171819sudo apt update && sudo apt upgrade -ysudo apt install -y \ nginx \ php \ php-cli \ php-mbstring \ unzip \ curl \ php-gd \ php-mysql \ php-xml \ php-curl \ php-zip \ php-bcmath \ php-fpm# 验证版本php -v ✅ 安装 Composer12345678cd ~curl -sS https://getcomposer.org/installer | phpsudo mv composer.phar /usr/local/bin/composer# 验证版本composer -V ✅ 安装 Flarum123cd ~mkdir flarumcomposer create-project flarum/flarum flarum ✅ 安装MariaDB123456789101112131415161718192021222324252627282930313233# 安装数据库sudo apt install mariadb-server -ysudo systemctl enable mariadbsudo systemctl start mariadb# 初始化,设置密码sudo mysql_secure_installation# 登录sudo mysql -u root -p# 设置密码ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyRootPass123!' ;# 设置远程访问CREATE USER 'root'@'%' IDENTIFIED BY 'MyRootPass123!';# 设置权限GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;# 创建数据库CREATE DATABASE flarum CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;# 刷新权限FLUSH PRIVILEGES;# 退出EXIT;# 开启远程访问sudo vim /etc/mysql/mariadb.conf.d/50-server.cnfbind-address = 127.0.0.1 -> bind-address = 0.0.0.0sudo systemctl restart mariadb ✅ 配置Nginx12345678910111213141516171819202122232425262728293031server { listen 80; server_name _; # ← 如果没有域名,可以写你的公网 IP root /home/ubuntu/flarum/public; index index.php index.html; # URL 重写规则 location / { try_files $uri $uri/ /index.php?$query_string; } # PHP 解析设置 location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # 禁止访问隐藏文件 location ~ /\.ht { deny all; } # 缓存静态资源 location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|ttf|svg|eot)$ { expires 6M; access_log off; add_header Cache-Control "public"; }} ✅ 修改文件全新到这一步,使用IP访问,会404,执行以下命令授权 1234sudo chown -R www-data:www-data /home/ubuntu/flarumsudo chmod -R 775 /home/ubuntu/flarum/storagesudo chmod -R 775 /home/ubuntu/flarum/public/assetssudo chmod +x /home/ubuntu ✅ 配置域名Cloudflare开启了正常CDN,还需要修改php的配置文件修改flarum目录下的config.php 1234567vim ~/flarum/config.php'url' => 'http://<原来的IP>',修改成'url' => 'https://forum.example.com', php flarum cache:clear 配置📤配置邮箱驱动:smtp 主机:smtp.gmail.com 顿口:587 加密协议:tls 用户名:发送验证码的邮箱 密码:Gmail应用程序的专用密码
JavaScript
JavaScript12345678910111213141516171819202122232425262728293031323334353637383940414243<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <title>setTimeout</title> </head> <body> <input type="text" id="displayBox" name="displayBox" value="0"> <div id="content"></div> <button type="button" onclick="countSecond()">开始计数</button> <!--例子4--> <button type="button" onclick="clearTimeout(stop)">停止计数</button> <script> // 例子1 setTimeout("alert('对不起, 要你久候')", 3000) // 例子2 setTimeout("changeState()", 1000); function changeState() { let content = document.getElementById('content'); content.innerHTML = "<div style='color:red'>我是三秒后显示的内容!</div>"; } // 例子3 x = 0 function countSecond() { x = x+1 document.getElementById("displayBox").value=x stop = setTimeout("countSecond()", 1000) } // 例子5 setTimeout(demo5, 3000,"1232") function demo5(msg) { alert(msg) } </script> </body></html> 函数JSJS声明普通函数 1234567// 声明函数-没有参数-没有返回值function showMessage() { console.log( 'Hello everyone!' );}// 调用函数showMessage(); 1234567// 声明有参数的函数function showMessage2(param1,param2){ console.log(param1, param2);}// 调用函数showMessage2("anthony",23) 12345678// 声明有默认值的函数function showMessage2(param1,param2=24){ console.log(param1, param2);}// 调用函数showMessage2("anthony",23)showMessage2("anthony") 1234567// 声明有返回值的函数function haveReturn(param1,param2){ return param1 + param2;}// 调用函数console.log(haveReturn(1,2))12345678910111213/** * 计算两个数字的和 * @param num1 - 第一个加数 * @param num2 - 第二个加数 * @returns 返回两个数字的和 */function add(num1: number, num2: number): number { return num1 + num2;}// 调用示例const result = add(5, 3);console.log(result); // 输出: 8 函数表达式 1234567891011let let1 = function sayHi(){ return 10086;}// 打印 [Function: sayHi]// 不像别的语言 调用let1的作用==let1(), js里调用函数就需要()console.info(let1)let let2 = let1console.info(let1());console.info(let2()); 回调 1234567891011121314151617181920212223242526272829function ask(question, yes, no) { if (question) { yes(); } else { no(); }}function showQuestion() { return 1 === 1;}function showOk() { console.info("同意");}function showCancel() { console.info("不同意");}// 用法:函数 showOk 和 showCancel 被作为参数传入到 askask(showQuestion(), showOk, showCancel);// 也可以写成ask(1 === 1, function () { console.info("同意"); }, function () { console.info("不同意"); }) 普通函数和函数表达式的区别 123456789101112sayHi("John"); // Hello, Johnfunction sayHi(name) { alert( `Hello, ${name}` );}----------------------------------------------------sayHi2("John"); // 报错,函数还没有创建!let sayHi2 = function(name) { // (*) no magic any more alert( `Hello, ${name}` );}; 箭头函数,功能是更简化函数表达式 定义 1234567891011121314151617let demo1 = function () { console.info("常用的函数表达式")};let demo2 =()=>console.info("单行的箭头函数")let demo3 =()=>{ console.info("单行的箭头函数第一行") console.info("单行的箭头函数第二行")}let demo4 = (name, age) => console.info("带参数的箭头表达式", name, age);demo1();demo2();demo3();demo4("Anthony", 24); 重新上面的例子 123456789let ask = (question, yes, no) => { question ? yes() : no();}// 也可以写成ask(() => 1 === 1, () => console.info("同意"), () => console.info("不同意")); 对象创建对象 123456789101112131415161718192021let user = { // 一个对象 name: "John", // 键 "name",值 "John" age: 30, // 键 "age",值 30 "likes birds": true // 多词属性名必须加引号};// 访问属性console.info(user.age)// 删除属性delete user.age;console.info(user.age)// 访问多词属性console.info(user["likes birds"])// 也可以访问普通属性console.info(user["name"])// 给对象添加属性,这样不行user.address="Dubai"user["sex"]="男"console.info(user.address)console.info(user.sex) 引用 1234567891011121314151617181920let user = { // 一个对象 name: "John", // 键 "name",值 "John" age: 30, // 键 "age",值 30};let user1 = userconsole.info(user1.name)user.name="anthony"console.info(user1.name)// 比较两个对象console.info(user === user1)// 浅拷贝,克隆对象,克隆user 给 user2let user2={}Object.assign(user2, user);console.info(user2.name)user.name="Nick"console.info(user2.name) 方法 12345678910111213141516171819202122232425262728293031let user = { // 一个对象 name: "John", // 键 "name",值 "John" age: 30, // 键 "age",值 30 // 给对象添加方法的第三种写法 sayHi3: function () { console.info(this.name) }, sayHi4: function () { let demo = ()=>{ console.info("箭头函数不能访问this"); } demo(); },};// 给对象添加方法的第一种写法user.sayHi = function () { console.info(this.name)};// 给对象添加方法的第二种写法function sayHi2() { console.info(this.name)}user.sayHi2 = sayHi2;// 调用对象方法user.sayHi()user.sayHi2()user.sayHi3()user.sayHi4() 数组 12345678910111213141516// 数组let arr = [];// 添加新元素arr[0] = "A"arr[1] = "B"arr[2] = "C"console.info("获取指定元素",arr[0])console.info("打印元素个数",arr.length)console.info("打印全部元素",arr)// 数组作为队列(push/pop),也可以做为栈(shift和unshift)arr.push("哈哈哈,存入输入")console.info("打印全部元素",arr)// 取出数据arr.pop()console.info("打印全部元素",arr) map 123456789101112131415// maplet map = new Map();map.set("k1","v1")map.set("k2","v2")map.set("k3","v3")// 访问数据console.info(map)console.info(map.get("k1"))console.info(map["k1"]) // 这样不行// 遍历for (const key of map.keys()) { console.info(map.get(key))}
nexus3
Docker仓库 类型 端口 仓库名字 Host 9083 My-docker-host proxy My-docker-proxy group 9082 My-docker-group 创建一个存储目录 名字随便起,没有太多影响  创建docker host仓库    创建proxy仓库   group  docker客户端配置 12345678# vim /etc/docker/daemon.json{ "insecure-registries": ["54.255.206.44:9082", "54.255.206.44:9083"]}# 需要重启systemctl daemon-reloadsystemctl restart docker 登录 登录之后凭证保存在/.docker/config.json或者是在,部署的时候遇到一个问题,就是jenkins打包之后docker login可以,但是push的时候就提示没有授权,暂时的解决办法是,宿主机docker login下,保存凭证,然后jenkins容器挂载/root/.docker/config.json这个文件,jenkins打包就可以不用登录,直接推送 12345678910111213root@anthony:~# docker login http://54.255.206.44:9083Username: adminPassword:Error response from daemon: login attempt to http://54.255.206.44:9083/v2/ failed with status: 401 Unauthorized# ----------------------------------------------------------------------------root@anthony:~# docker login http://54.255.206.44:9082Username: adminPassword:WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded 123456789# 镜像操作# pull镜像docker pull nginx:latest# 给镜像打tagdocker tag nginx:latest 54.255.206.44:9082/my-docker-host/nginx:latest# 推送镜像docker push 54.255.206.44:9082/my-docker-host/nginx:latest
Docker
docker安装CentosUbuntu12345678910111213141516# 卸载旧版本sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine# 安装sudo yum install -y yum-utils device-mapper-persistent-data lvm2# 添加yum源sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo# 安装yum -y install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpmyum -y install docker-ce启动systemctl enable dockersystemctl start docker12# 用于系统是干净的,如果重新装,需要吧原来的docker卸载掉sudo apt install docker.io 开启远程访问1234567891011121314# 编辑vim /lib/systemd/system/docker.service# 默认是这样的ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # 修改成ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock# 重启systemctl daemon-reloadsystemctl restart docker# 测试curl http://localhost:2375/version 查看远端仓库的标签创建一个dockertags.sh脚本 12345678910111213141516171819202122232425262728293031#!/bin/bashfunction usage() { cat << HELPdockertags -- list all tags for a Docker image on a remote registry.EXAMPLE: - list all tags for ubuntu: dockertags ubuntu - list all php tags containing apache: dockertags php apacheHELP}if [ $# -lt 1 ]; then usage exitfiimage="$1"tags=`wget -q https://registry.hub.docker.com/v1/repositories/${image}/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}'`if [ -n "$2" ]then tags=` echo "${tags}" | grep "$2" `fiecho "${tags}" 12345# 给权限chmod +x dockertags.sh# 使用./dockertags.sh mysql WARNING: IPv4 forwarding is disabled. Networking will not work是没有开启转发,docker网桥配置完后,需要开启转发,不然容器启动后,就会没有网络 修改配置文件: 12345678# vim /etc/sysctl.confnet.ipv4.ip_forward=1 #添加此行配置# 重启network和docker服务systemctl restart network && systemctl restart docker# 查看是否修改成功,如果返回为“net.ipv4.ip_forward = 1”则表示修改成功sysctl net.ipv4.ip_forward 常用命令12345# 查看镜像源,最下面能看到docker info# 查看镜像/容器/数据卷所占的空间docker system df xxx 镜像查看镜像 12# 列出本地主机上的镜像docker images REPOSITORY:表示镜像的仓库源 TAG:镜像的标签 IMAGE ID:镜像ID CREATED:镜像创建时间 SIZE:镜像大小 下载镜像 12345# 查找镜像docker search ubuntu:13.10# 只是直接下载docker pull ubuntu:13.10 删除镜像 12345678# 删除指定镜像docker image rm <id># 删除名字是none的镜像docker rmi $(docker images | grep "none" | awk '{print $3}')# 删除全部镜像docker rmi -f $(docker image -qa) 容器运行容器 1docker run -p 10001:10001 -t springboot/eureka-item 1docker run -it --rm ubuntu:16.04 bash docker run 运行容器的命令 -i 以交互模式运行,通常与-t一起使用 -t 为容器重新分配一个伪输入终端,通常与-i一起使用 bash 进入交互式终端,通常使用/bin/bash -p 指定端口 -P 随机分配端口 -d 后台运行容器并返回容器Id,即启动守护式容器 查看容器 12345678# 查看正在运行的容器docker ps # 查看所有容器docker ps -a# 列出所有的容器 IDdocker ps -aq 启动容器 12#启动已终止容器docker container start 05909cd09bf9 重启容器 1docker restart id 停止容器 1234567891011121314# 停止容器docker stop myredis# 强制停止容器docker kill myredis# 停止所有的容器docker stop $(docker ps -aq)# 删除所有的容器docker rm $(docker ps -aq)# 强制删除,在运行的容器也会删除docker rm -f myredis 容器日志 1docker logs xxx 进入容器12345# 不会启动新的进程,用exit退出,会导致容器的停止docker attach 5cc239848ce5# 打开新的终端,启用新的进程,用exit退出,不会导致容器的停止docker exec -it 5cc239848ce5 /bin/bash 进入容器修改时区,需要重启容器 12ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeecho "Asia/Shanghai" > /etc/timezone 拷贝文件12345678# 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。docker cp /www/runoob 96f7f14e99ab:/www/# 将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为wwwdocker cp /www/runoob 96f7f14e99ab:/www# 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中docker cp 96f7f14e99ab:/www /tmp/ 导出/入容器第一种方式: 1234567# 如果要导出本地某个容器,可以使用 docker export 命令。docker export 1e560fca3906 > ubuntu.tar# docker import 从容器快照文件中再导入为镜像,# 以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:# 格式: cat 文件名 | docker import - xxx(镜像用户,自定义)/xxx(镜像名,自定义):xxx(版本号自定义)cat docker/ubuntu.tar | docker import - test/ubuntu:v1 第二种方式: 12345# 镜像转文件docker save -o demo.tar(自定义) 镜像名:版本号# 文件转镜像docker load -i demo.tar Commit1docker commit -a "runoob.com" -m "my apache" a404c6c174a2 mymysql:v1 过时:容器不能上网1234vim /etc/sysctl.conf增加:net.ipv4.ip_forward=1重启服务:systemctl restart network查看属性是否修改成功:sysctl net.ipv4.ip_forward 过时:停止和查看容器12345#查看所有的容器(已经存在的容器,已经停止的)docker container ls -a#停止容器docker container stop 05909cd09bf9 过时:Jenkins容器脚本12345678910111213APP_NAME=springboot/lottery-adminecho "当前容器列表"docker ps -a | grep $APP_NAMEecho "star service success!"count = ’docker ps -a |grep $APP_NAME |wc -l‘if [$count -ge 1];thendocker stop $APP_NAMEdocker rm $APP_NAMEfi 123456789101112131415161718192021appName="simons-cloud-eureka"word="1"echo "$word"word=`docker ps -a -q --no-trunc --filter name=^/"$appName"$`echo "$word"if [ -z "$word" ];thenecho "当前不存在该容器,直接进行启动该操作-------------------------------------"elif [ -n "$word" ];thenecho "当前已存在容器,停止并移除该容器-------------------------------------"/usr/bin/docker stop "$word"/usr/bin/docker rm "$word"elif [ "$word" == "1" ];thenecho "查询的信息有误,执行默认操作-------------------------------------"/usr/bin/docker stop "$word"/usr/bin/docker rm "$word"fidocker run -p 8761:8761 -d --name "$appName" "$appName":latest 挂载目录1234567891011121314151617181920docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu# --privileged=true 用来扩容权限用的,最好是加上# -v 宿主目录:容器目录,运行容器的时候,会自动创建目录# 查看挂载情况"Mounts": [ { "Type": "bind", "Source": "/tmp/host_data", "Destination": "/tmp/docker_data", "Mode": "", "RW": true, "Propagation": "rprivate" }]# 继承挂载# 再启动一个容器,起名叫u2,u2的挂载目录,跟u1的一样,就继承u1的挂载目录# 特点是,就算u1停了,也不会影响这个docker run -it --privileged=true --volumes-fron u1 --name=u2 ubuntu DcokerfileExpose暴露端口 1234567891011121314151617# GET_IMAGEFROM 192.168.0.216:5000/centos # MAINTAINER_INFOMAINTAINER hongxue [email protected] RUN yum -y install vimRUN yum -y install net-toolsRUN yum -y install openssh-serverRUN yum -y install wget curl # PORTEXPOSE 8080EXPOSE 22EXPOSE 8009EXPOSE 8005EXPOSE 8443 1docker run -d -it -P --name port_list_container port_list 要使用-P ,绑定的宿主端口,会是随机的 所以Dockerfile的EXPOSE的主要功能,也只是给运维人员看看的 网络123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869# 查看Docker网络,默认的3大网络模式root@anthony:~# docker network lsNETWORK ID NAME DRIVER SCOPEa4154cc357c5 bridge bridge local6625ad672ae9 host host local497caf91f24e none null local# 创建一个网络docker network create xxxx# 删除一个网络docker network rm xxxx# 查看网络docker network inspect xxx root@anthony:~# docker network inspect bridge[ { "Name": "bridge", "Id": "a4154cc357c50d0ac961d8235101d8e199119d5677b911ca84ff49962039a53a", "Created": "2023-10-27T00:40:28.869797225Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "a59c6dd9d8bbdbc4f760389bd85af69786e632e6bd1d346c542d6886f572872b": { "Name": "u1", "EndpointID": "e54ed02028a063b38390abac5306cba4f97ff40135b0cfab2370c950f5ae11dc", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "b5615376be36a2b28485a93fa62d10d9886c53c9f59c5fbcd00de78b0184d6b7": { "Name": "tomcat", "EndpointID": "23688ac53c0f16a8abd20bbe4e64539266645019ce95501253577cf57fc71b7a", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", # 网桥名字 "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} }] docker-composeDocker Compose 安装1234567891011# 可以修改版本 curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose# 给权限sudo chmod +x /usr/local/bin/docker-compose# 超链接sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose# 验证docker-compose --version 命令12345# 启动docker-compose up# 后台启动docker-compose up -d 部署到私有仓库12345678910111213141516171819202122232425//位置gedit /etc/default/docker//添加的命令DOCKER_OPTS="–insecure-registry 172.20.100.211:5000"//重启service docker restart//打tagdocker tag springboot/eureka-item 172.20.100.211:5000/anthonyfirst//推送docker push 172.20.100.211:5000/anthonyfirst//获取私有仓库里的信息curl -XGET http://172.20.100.211:5000/v2/_catalog#客户端配置私有仓库修改/etc/sysconfig/docker(Ubuntu下配置文件地址为:/etc/init/docker.conf),增加启动选项(已有参数的在后面追加),之后重启docker,不添加报错,https证书问题。OPTIONS='--insecure-registry 172.20.100.211:5000' #CentOS 7系统#重启服务systemctl daemon-reloadsystemctl restart docker 报错信息1.缺少FontConfiguration知道是因为alpine中缺少FontConfiguration,那么就考虑安装ttf-dejavu这个软件。 123456789101112131415161718192021222324252627282930313233java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264) at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219) at sun.awt.FontConfiguration.init(FontConfiguration.java:107) at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774) at sun.font.SunFontManager$2.run(SunFontManager.java:431) at java.security.AccessController.doPrivileged(Native Method) at sun.font.SunFontManager.<init>(SunFontManager.java:376) at sun.awt.FcFontManager.<init>(FcFontManager.java:35) at sun.awt.X11FontManager.<init>(X11FontManager.java:57) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83) at java.security.AccessController.doPrivileged(Native Method) at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) at java.awt.Font.getFont2D(Font.java:491) at java.awt.Font.access$000(Font.java:224) at java.awt.Font$FontAccessImpl.getFont2D(Font.java:228) at sun.font.FontUtilities.getFont2D(FontUtilities.java:180) at sun.font.StandardGlyphVector.initFontData(StandardGlyphVector.java:1126) at sun.font.StandardGlyphVector.init(StandardGlyphVector.java:1115) at sun.font.StandardGlyphVector.<init>(StandardGlyphVector.java:167) at java.awt.Font.createGlyphVector(Font.java:2545) at nl.captcha.text.renderer.DefaultWordRenderer.render(Unknown Source) at nl.captcha.Captcha$Builder.addText(Unknown Source) at com.liferay.portal.captcha.simplecaptcha.SimpleCaptchaImpl.getSimpleCaptcha(SimpleCaptchaImpl.java:243) at com.liferay.portal.captcha.simplecaptcha.SimpleCaptchaImpl.serveImage(SimpleCaptchaImpl.java:159) at com.liferay.portal.captcha.CaptchaImpl.serveImage(CaptchaImpl.java:100) at com.liferay.portal.kernel.captcha.CaptchaUtil.serveImage(CaptchaUtil.java:78) at com.liferay.portal.captcha.CaptchaPortletAction.serveResource(CaptchaPortletAction.java:42) 原本的dockerfile 1234FROM openjdk:8-jdk-alpineVOLUME /tmpADD agent-0.0.1-SNAPSHOT.jar app.jarENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 要改成下面这样RUN apk --update add fontconfig ttf-dejavu 12345FROM openjdk:8-jdk-alpineVOLUME /tmpADD agent-0.0.1-SNAPSHOT.jar app.jarRUN apk --update add fontconfig ttf-dejavuENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 2.WARNING: HK2 service reification failed for…12345678910111213141516java.lang.NoClassDefFoundError: javax/activation/DataSource at java.base/java.lang.Class.getDeclaredConstructors0(Native Method) at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3110) at java.base/java.lang.Class.getDeclaredConstructors(Class.java:2314) at org.jvnet.hk2.internal.Utilities$3.run(Utilities.java:1310) at org.jvnet.hk2.internal.Utilities$3.run(Utilities.java:1306) at java.base/java.security.AccessController.doPrivileged(Native Method) at org.jvnet.hk2.internal.Utilities.getAllConstructors(Utilities.java:1306) at org.jvnet.hk2.internal.Utilities.findProducerConstructor(Utilities.java:1249) at org.jvnet.hk2.internal.DefaultClassAnalyzer.getConstructor(DefaultClassAnalyzer.java:83) at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:144) at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:178) at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:128) at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:179) at org.jvnet.hk2.internal.SystemDescriptor.internalReify(SystemDescriptor.java:723) at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:678) 在pom.xml里添加 123456789101112<plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> // ...... <dependencies> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> </dependencies></plugin> 3.不能链接daemon服务没有启动,运行docker,会报这个错 1docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. 需要启动docker service 1service docker start 安装软件安装Jenkins12345678910111213141516docker run -d \ -u root \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(which docker):/usr/bin/docker \ -p 8080:8080 \ -p 50000:50000 \ -v /home/jenkins:/var/jenkins_home \ --restart=always \ --name jenkins \ jenkins/jenkins:lts # 查看密码# 容器里的位置cat /var/jenkins_home/secrets/initialAdminPassword# 宿主机的位置cat /root/jenkins/secrets/initialAdminPassword 4.安装插件完之后,安装maven插件,在主机上下载maven,上传到容器中 1234docker cp maven-3.6.0 jenkins:/usr/local/// 上传本机的配置文件docker cp settings.xml jenkins:/home/ 5.进入容器 12345// 普通用户的权限docker exec -it jenkins bash// sudo的用户权限docker exec -it -u 0 jenkins bash 6.从本机拷贝到容器,是不需要用到权限的,但是在容器内,比如从/home下的文件移动到/root 就需要权限,就需要使用 -u 0 在Docker容器的Jenkins,构建SpringBoot 的jar包再执行Shell运行的时候,连接数据库可能有坑,数据库会连不上 安装ElasticSearch12345678910111213docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.3.2docker exec -it es /bin/bashcd configvi elasticsearch.yml# 加入跨域配置http.cors.enabled: truehttp.cors.allow-origin: "*"docker restart es 安装Portainer12345678910111213# 创建数据卷docker volume create portainer_data# 9000才是web访问的端口docker run -d \ -p 8000:8000 \ -p 9000:9000 \ -p 9443:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /docker/portainer:/data \ portainer/portainer-ce:2.21.1 1234567891011121314151617server { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:9000; # 将请求转发到 Portainer 后端 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }} 添加docker nodehttps://blog.csdn.net/bj_chengrong/article/details/90300972 安装Redis123456789101112131415# 简单的执行docker run -itd \ --name redis \ --restart=always \ -p 6379:6379 \ redis# 持久化执行docker run -d \ --name redis \ -p 6379:6379 \ -v /docker/redis/config/redis.conf:/usr/local/etc/redis/redis.conf \ -v /docker/redis/data:/data \ --restart=always \ redis redis-server /usr/local/etc/redis/redis.conf 新建redis.conf,位置在:/docker/redis/config/redis.conf 1234567891011#启用 RDB 快照持久化save 900 1save 300 10save 60 10000#启用 AOF 持久化appendonly yesappendfsync everysec#设置持久化目录dir /data 安装Mysql1234567891011# 正式配置# 在对应目录先创建my.cnf文件, 不然系统会自动创建my.cnf文件夹....# 本地对应的目录文件夹会自动创建docker run -itd \ --name mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /Users/anthony/docker/mysql/config/my.cnf:/etc/mysql/conf.d/my.cnf \ -v /Users/anthony/docker/mysql/data:/var/lib/mysql \ --restart=always \ mysql 最简单的my.cnf配置文件 1234567[mysqld]# 时区default-time-zone=+08:00# 字符集character-set-server=utf8mb4# 创建函数/存过的时候,会报安全问题,不用存过/函数,不用管log_bin_trust_function_creators=1; 容器文档:Mysql 安装 Nginx123456789101112131415# 简单的docker run --name nginx-test \ -p 8080:80 \ -d \ nginx# 正式的docker run -d \ -p 443:443 \ -p 80:80 \ --name nginx \ -v /home/nginx/www:/usr/share/nginx/html \ -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \ -v /home/nginx/logs:/var/log/nginx \ nginx nginx.conf模板 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576# 用户 nginx 使用的工作进程user nginx;# 允许的工作进程数,自动检测 CPU 核心数worker_processes auto;# 错误日志路径和日志级别error_log /var/log/nginx/error.log warn;# PID 文件路径pid /var/run/nginx.pid;events { # 单个工作进程允许的最大连接数 worker_connections 1024;}http { include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式配置 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 访问日志路径 access_log /var/log/nginx/access.log main; # 启用 Gzip 压缩 gzip on; gzip_disable "msie6"; # 启用发送文件优化 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/conf.d/*.conf; # 默认服务器配置 server { listen 80 default_server; server_name localhost; # 站点根目录 root /usr/share/nginx/html; # 主页文件 index index.html index.htm; # 处理静态文件请求 location / { try_files $uri $uri/ =404; } # 配置反向代理 # 如果你需要反向代理到一个后端服务,可以启用以下代码: # location /api/ { # proxy_pass http://backend_service; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto $scheme; # } # 错误页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }} 安装nexus 3123456789101112131415# 创建数据文件夹mkdir /docker/nexus3/nexus-data# 如果有权限问题chmod 777 /docker/nexus3/nexus-datadocker run -d \ -p 8081:8081 \ --name nexus \ -v /docker/nexus3/nexus-data:/nexus-data \ --restart=always \ sonatype/nexus3# 查看密码cat /docker/nexus3/nexus-data/admin.password 安装Elastic Search12345678docker run -itd \ -p 9200:9200 \ -p 9300:9300 \ -e "discovery.type=single-node" \ -v /home/anthony/es/config:/usr/share/elasticsearch/config/ \ --name elasticsearch \ --restart=always \ docker.elastic.co/elasticsearch/elasticsearch:7.7.0 安装Zookeeper1docker run -d -p 2181:2181 --name some-zookeeper --restart=always zookeeper 安装可视化软件 mac安装的使用要查看下说明文档,会出现安装包损坏的情况 安装Grafana12# admin / admindocker run -d -p 3000:3000 --name=grafana grafana/grafana 安装WordPressdocker-compose安装WordPress 安装禅道12345678910111213141516# 内置数据库docker run -d -v <你的宿主机目录>/data:/data -p 80:80 -e MYSQL_INTERNAL=true hub.zentao.net/app/zentao # 外接数据库,web页面的安装向导,点击确定之后要等一会docker run -itd \ -v /docker/zentao/data:/data \ -p 8001:80 \ -e MYSQL_INTERNAL=false \ -e ZT_MYSQL_HOST=172.17.0.3 \ -e ZT_MYSQL_PORT=3306 \ -e ZT_MYSQL_USER=root \ -e ZT_MYSQL_PASSWORD=Qwer1234. \ -e ZT_MYSQL_DB=zentao \ --restart=always \ --name zentao \ hub.zentao.net/app/zentao 禅道官方文档 安装Nacosmac docker 安装nacos 12345docker run -d \ -p 8848:8848 \ --env MODE=standalone \ --name nacos \ zhusaidong/nacos-server-m1:2.0.3 访问地址:http://localhost:8848/nacos/ 账号/密码:nacos/nacos Nacos官方文档
Grafana
监控主机 HostName IP master 10.0.0.6 node1 10.0.0.9 服务 端口 Grafana 3000 Prometheus 9090 node-exporter 9100 Cadvisor 8080 部署Prometheus(master机器)123456docker run -d \ --name=prometheus \ --restart=always \ -p 9090:9090 \ -v /root/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \ prom/prometheus 编辑prometheus.yml配置文件 12345678910111213scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['10.0.0.6:9090'] #添加master及node节点添加 - job_name: 'master' static_configs: - targets: ['10.0.0.6:9100'] - job_name: 'node' static_configs: - targets: ['10.0.0.9:9100'] 这里只是提前编辑好,之后如果要添加新的机器,再后面添加 访问master的9090端口,http://10.0.0.6:9090/ 部署node_exporter(master和node)看需求,master不部署也可以 docker安装源码安装12345678docker run -d \ --name node-exporter \ --restart=always \ -p 9100:9100 \ -v "/proc:/host/proc:ro" \ -v "/sys:/host/sys:ro" \ -v "/:/rootfs:ro" \ prom/node-exporter12345678910111213141516171819202122232425262728293031323334353637# 下载最新的node_exporter版本wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz# 解压缩下载的文件tar xvfz node_exporter-1.6.1.linux-amd64.tar.gz# 将可执行文件移动到 /usr/local/binsudo mv node_exporter-1.6.1.linux-amd64/node_exporter /usr/local/bin/# 创建 node_exporter 用户useradd -rs /bin/false node_exporter# 创建 systemd 服务vim /etc/systemd/system/node_exporter.service[Unit]Description=Node ExporterWants=network-online.targetAfter=network-online.target[Service]User=node_exporterGroup=node_exporterType=simpleExecStart=/usr/local/bin/node_exporter[Install]WantedBy=multi-user.target# 重新加载 systemd 配置sudo systemctl daemon-reload# 启动 node_exporter 服务sudo systemctl start node_exporter# 设置为开机自动启动sudo systemctl enable node_exporter 验证访问http://<你的服务器IP>:9100/metrics 点击Mertrics,下图为node通过9100端口暴露出的监控指标 再次访问master的9090端口,就会显示上面的 UP 状态 再修改prometheus.yml 1234scrape_configs: - job_name: 'node_exporter' static_configs: - targets: ['<你的服务器IP>:9100'] 部署Grafana12345678910111213# 新建空文件夹grafana,用来存储数据mkdir /root/grafana# 设置权限chmod 777 -R /root/grafana# 运行docker run -d \ -p 3000:3000 \ --name=grafana \ -e "GF_SECURITY_ADMIN_PASSWORD=admin" \ -v /root/grafana:/var/lib/grafana \ grafana/grafana 访问master的3000端口 默认账号密码都为admin 创建数据源 联接Prometheus 点击Save & Test 创建面板 点击Import 输入模板代码9276 点击Load 再下拉框选中Prometheus 点击Import 查看,选中要查看的主机 监控节点主机的容器cAdvisor(Container Advisor)用于采集正在运行的容器资源使用和性能信息。 cAdvisor可以对节点机器上的资源及容器进行实时监控和性能数据采集,包括CPU使用情况内存使用情况 网络吞吐量及文件系统使用情况 部署Cadvisor12345678910docker run -d \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:ro \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --volume=/dev/disk/:/dev/disk:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest 访问节点IP+端口 修改prometheus.yml,在末尾添加,修改玩之后要重启Prometheus 123- job_name: 'docker' static_configs: - targets: ['10.0.09:8080'] 访问节点IP+9090 然后在master主机登录Grafana,导入Docker监模板,id:193 在docker中搭建micrometer + grafana + prometheus的jvm监控 - 掘金 监控Mysql123456docker run -d \ --name mysql_exporter \ --restart always \ -p 9104:9104 \ -e DATA_SOURCE_NAME="root:123456@(10.0.0.8:3306)/" \ prom/mysqld-exporter 模板ID:7362
Mysql
常见问题字符集问题修改mysql的数据陆慕下的my.ini的配置文件(Windows系统) 12345[mysql] #大概在63行左右,在其下添加default-character-set=utf8 #默认字符集[mysqld] # 大概在76行左右,在其下添加character-set-server=utf8 collation-server=utf8_general_ci 注意:建议修改配置文件使用notepad++等高级文本编辑器,使用记事本等软件打开修改后可能会导致文件编码修改为“含BOM头”的编码,从而服务重启失败 重启服务,再查看一次编码 修改编码前,已经创建的表和库,修改编码后不会自动更改,需要重新建库表或者手动修改库表的编码 手动修改库表的编码 12345678#修改数据库的字符编码为utf8 alter database test charset utf8; #修改表字符编码为UTF8alter table student charset utf8; #修改字段字符编码为UTF8alter table student modify name varchar(20) charset utf8; 客户端连接的问题旧版本图形界面工具连接MySQL8时出现Authentication plugin caching_sha2_password' cannot be loaded错误。 MySQL8之前的版本中加密规则是mysql_native_password, MySQL8之后的加密规则是caching_sha2_password 解决问题: 修改用户名为“root@localhost”的用户密码规则为“mysql_native_password”,密码值为“123456” 1234567891011121314151617181920212223# 查看所有数据库mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || ry-vue || sys |+--------------------+5 rows in set (0.01 sec)# 使用mysql数据库,不需要要分号,其余的命令要加分号use mysql;# 修改'root'@'localhost'用户的密码规则和密码ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'abc123';FLUSH PRIVILEGES;# 开启远程访问UPDATE user SET host='%' WHERE user='root';FLUSH PRIVILEGES; 存过报错报错信息: 1[Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) 我们就必须指定我们的函数是否是: DETERMINISTIC 不确定的 NO SQL 没有SQl语句 READS SQL DATA 只是读取数据 MODIFIES SQL DATA 要修改数据 CONTAINS SQL 包含SQL语句 其中在function/procedure 里面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。 如果我们开启了 bin-log, 我们就必须为我们的function/procedure 指定一个参数。 解决方法: 方法1:临时修改方法2配置文件修改方法3:执行sql的时候添加信息1234# 在mysql数据库中执行以下语句 (临时生效,重启后失效)set global log_bin_trust_function_creators=TRUE;# 或者set global log_bin_trust_function_creators=1;12# 在配置文件/etc/my.cnf的[mysqld]或者my-default.ini文件中配置log_bin_trust_function_creators=112345678CREATE DEFINER=`root`@`localhost` FUNCTION test(param bigint) RETURNS decimal(10,0)# 需要添加这个READS SQL DATAREADS SQL DATABEGIN ....RETURN .....;END 常用SQL例子1234-- select 嵌套子查询select (select count(id) from user_info) as a, (select count(id) from user_info where age > 10) as b; 123-- 用到的函数,查询日期select curdate();select date(now()); 123456/* user_info已经筛选过一次, 再这之后再筛选一次 用的金额 */SELECT SUM(CASE WHEN status = 1 THEN amount ELSE 0 END) AS '冻结的用户的总金额', SUM(CASE WHEN status = 2 THEN amount ELSE 0 END) AS '活跃的用户的总金额'FROM user_info where register between '2020-02-02' and '2023-02-02'; 123-- insert的字段数据,需要查询出来的数据insert into bank_info(bank_code, bank_name)VALUES ('NEW', (select user_no from user_fund_info where id = 46)); 优化的例子优化大表的查询,查询一张流水表,要统计开始时间和时间之间的数据 12345678910111213141516171819202122232425262728293031323334353637-- 业务是:一个用户,流水在这个时间段最多只有一条记录,并且查询所有用户在这个时间段一共有多少条记录-- 流水表目前的数据量有70w-- 这样查询,需要好几秒的时间,explain的行数是70wSELECT count(1)FROM users AS t1 LEFT JOIN liushui AS t2 ON t1.id = t2.user_id and t2.begin_time <= '2023-09-14 21:01:28' AND t2.open_time >= '2023-09-14 21:01:28' ; -- 进行优化-- 增加了一个belong_date的字段,并且添加索引-- begin_time 和 open_time 有可能之间跨天了,所以belong_date要筛选两天的-- explain的行数只有2000多条SELECT count(1)FROM users AS t1 LEFT JOIN liushui AS t2 ON t1.id = t2.user_id AND t2.belong_date IN ('2023-09-14','2023-09-13') and t2.begin_time <= '2023-09-14 21:01:28' AND t2.open_time >= '2023-09-14 21:01:28' ; -- 再进行优化-- 上面的sql和这个sql explain 看着差不多一样,索引出来的流水表的数据量都是一样,可就是上面这条记录查询慢,下面这条记录查询快-- explain的行数只有2000多条-- 查询查询出来的效果是,先用belong_date查一遍,再在子查询的结果集再筛选一遍SELECT COUNT( 1 ) FROM ( SELECT t1.id t2.begin_time, # 这两个时间字段对业务是没有用的,是为了外面这个查询使用到 t2.open_time FROM lottery_open AS t1 LEFT JOIN lottery_period AS t2 ON t1.id = t2.lottery_id AND t2.belong_date IN ( CURDATE(), DATE_SUB( CURDATE(), INTERVAL 1 DAY ) )) AS t3 WHERE t3.begin_time <= '2023-09-14 21:01:28' AND t3.open_time >= '2023-09-14 21:01:28'; 实战mysql使用source导入数据导入的数据,中文乱码,只要先执行uft-8登录之后,再导入数据 1234567891011# 登录mysqlmysql -u root -p --default-character-set=utf8# 显示所有数据库show databases;# 选择数据库use [数据库]# 导入文件mysql> source d:\mysqldb.sql 导出1234567# --default-character-set=utf8 编码# -h 192.168.8.2 数据库地址# -u root 数据库用户名# -p# test 数据库库名# test.sql 导出sql的文件名mysqldump --default-character-set=utf8 --single-transaction --set-gtid-purged=OFF -h 192.168.8.2 -u root -p test > test.sql 语法比较运算符 12345678910111213141516171819202122232425262728# 字符串存在隐式转换,如果转换不成功,就看做0# 两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。# 两边的值都是整数,则MySQL会按照整数来比较两个值的大小。mysql> select 1=1,1=2,1!=2,2='2',1='a',0='a';+-----+-----+------+-------+-------+-------+| 1=1 | 1=2 | 1!=2 | 2='2' | 1='a' | 0='a' |+-----+-----+------+-------+-------+-------+| 1 | 0 | 1 | 1 | 0 | 1 |+-----+-----+------+-------+-------+-------+1 row in set, 2 warnings (0.00 sec)# 字符串和字符串比较,就不隐式转换了mysql> select 'a'='a','ab'='ab','a'='b';+---------+-----------+---------+| 'a'='a' | 'ab'='ab' | 'a'='b' |+---------+-----------+---------+| 1 | 1 | 0 |+---------+-----------+---------+1 row in set (0.00 sec)# 两边的值、字符串或表达式中有一个为NULL,则比较结果为NULL。mysql> select 1=null,null=null;+--------+-----------+| 1=null | null=null |+--------+-----------+| NULL | NULL |+--------+-----------+1 row in set (0.01 sec) 安全等于运算符 安全等于运算符<=>与等于运算符=的作用是相似的,唯一的区别:<=>可 以用来对NULL进行判断。 在两个操作数均为NULL时,其返回值为1,而不为NULL;当一个操作数为NULL 时,其返回值为0,而不为NULL。 1234567891011121314151617181920212223242526272829303132333435363738394041mysql> select 1<=>1,1<=>2,2<=>'2',1<=>'a',0<=>'a';+-------+-------+---------+---------+---------+| 1<=>1 | 1<=>2 | 2<=>'2' | 1<=>'a' | 0<=>'a' |+-------+-------+---------+---------+---------+| 1 | 0 | 1 | 0 | 1 |+-------+-------+---------+---------+---------+1 row in set, 2 warnings (0.00 sec)mysql> select 'a'<=>'a','ab'<=>'ab','a'<=>'b';+-----------+-------------+-----------+| 'a'<=>'a' | 'ab'<=>'ab' | 'a'<=>'b' |+-----------+-------------+-----------+| 1 | 1 | 0 |+-----------+-------------+-----------+1 row in set (0.00 sec)mysql> select 1<=>null,null<=>null;+----------+-------------+| 1<=>null | null<=>null |+----------+-------------+| 0 | 1 |+----------+-------------+1 row in set (0.00 sec)#查询commission_pct等于0.40# 有数据SELECT employee_id,commission_pct FROM employees WHERE commission_pct = 0.40;# 没有数据SELECT employee_id,commission_pct FROM employees WHERE commission_pct = null;# 有数据SELECT employee_id,commission_pct FROM employees WHERE commission_pct is null;# 有数据SELECT employee_id,commission_pct FROM employees WHERE commission_pct <=> 0.40; # 只会查出commission_pct = null的SELECT employee_id,commission_pct FROM employees WHERE commission_pct <=> null; 非空运算符 12345678910#查询commission_pct等于NULL。比较如下的四种写法SELECT employee_id,commission_pct FROM employees WHERE commission_pct IS NULL; SELECT employee_id,commission_pct FROM employees WHERE commission_pct <=> NULL;# 有点像调用函数了,也是判断null的SELECT employee_id,commission_pct FROM employees WHERE ISNULL(commission_pct);# 不要这样写SELECT employee_id,commission_pct FROM employees WHERE commission_pct = NULL;# 习惯用就用,不习惯就换一种用法SELECT employee_id,commission_pct FROM employees WHERE NOT commission_pct <=> NULL; between and 12345# 查看年纪在23到230之间select * from table where age between 23 and 230# 查询年纪不再23和230之间的select * from table where age not between 23 and 230 In 和 not in 12345# inselect last_name,salary,department_id from employees where department_id in(10,20,30);# not inselect last_name,salary,department_id from employees where department_id not in(10,20,30); or 1234# 这两个查询出来的结果是不一样的,一定要仔细select last_name,salary,department_id from employees where department_id=10 or department_id=20 or department_id=30select last_name,salary,department_id from employees where department_id=10 or 20 or 30 like 12345678910111213141516171819202122# %代表不确定个数的字符select last_name from employees where last_name like '%a%';# %代表不确定个数的字符select last_name from employees where last_name like 'a%';# 包含字符a 并且 好办字符e的# 第一种写法select last_name from employees where last_name like '%a%' and last_name like '%e%' ;# 第二种写法select last_name from employees where last_name like '%a%e%' or last_name like '%e%a%';# 第三种写法# 强制第二个符号是a的,_表示一个不确定的字符select last_name from employees where last_name like '_a%';# 转义字符# 查询第二个字符是下划线,并且第三个字符串是a的员工select last_name from employees where last_name like '_\_a%';# 或者# 告诉mysql,&是我自定义的转移字符select last_name from employees where last_name like '_&_a%' escape '&'; 正则表达式 1234567mysql> SELECT 'shkstart' REGEXP '^s', 'shkstart' REGEXP 't$', 'shkstart' REGEXP 'hk';+------------------------+------------------------+------------------------+| 'shkstart' REGEXP '^s' | 'shkstart' REGEXP 't$' | 'shkstart' REGEXP 'hk' |+------------------------+------------------------+------------------------+| 1 | 1 | 1 |+------------------------+------------------------+------------------------+1 row in set (0.01 sec) NOT或者! 当给定的值为0 (False)时 NOT FALSE => 1 当给定的值为非0值时返回0; 当给定的值为NULL时,返回NULL。 1234567891011# 把1当做true# NOT1 ==> Not True== False=0# not(2)==>2 是true ==>false=0# NOT !1==> NOT !True ==> NOT False==> True ==>1mysql> SELECT 1=1,NOT 1, NOT 0, NOT(1+1),not(2), NOT !1, NOT NULL;+-----+-------+-------+----------+--------+--------+----------+| 1=1 | NOT 1 | NOT 0 | NOT(1+1) | not(2) | NOT !1 | NOT NULL |+-----+-------+-------+----------+--------+--------+----------+| 1 | 0 | 1 | 0 | 0 | 1 | NULL |+-----+-------+-------+----------+--------+--------+----------+1 row in set, 1 warning (0.00 sec) AND或者 && 当给定的所有值均为非0值,并且都不为NULL时,返回 1; 当给定的一个值或者多个值为0时则返回0; 否则返回NULL。 1234567# 1 理解成True,其它的值就不管用# 1 or -1 ,有一路是通电的,那就是通电的mysql> SELECT 1 OR -1, 1 OR 0, 1 OR NULL, 0 || NULL, NULL || NULL;+---------+--------+-----------+-----------+--------------+| 1 OR -1 | 1 OR 0 | 1 OR NULL | 0 || NULL | NULL || NULL |+---------+--------+-----------+-----------+--------------+| 1| 1| 1|NULL| NULL| +---------+--------+-----------+-----------+--------------+ 1 row in set, 2 warnings (0.00 sec) limit 格式:LIMIT [位置偏移量,] 行数 第一个“位置偏移量”参数指示MySQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移 量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是 1,以此类推); 第二个参数“行数”指示返回的记录条数。 MySQL 8.0中可以使用“LIMIT 3 OFFSET 4”,意思是获取从第5条记录开始后面的3条记录,和“LIMIT 4,3;”返回的结果相同。 分页显式公式 :(当前页数-1)*每页条数,每页条数 1SELECT * FROM table LIMIT(PageNo - 1)*PageSize,PageSize; 注意:LIMIT 子句必须放在整个SELECT语句的最后! order by 单列排序 12345# 默认升序select salary from employees order by salary# 使用列的别名,进行排序select salary,salary*12 as year_salary from employees order by year_salary 多列排序 123select employee_id, salary, department_idfrom employeesorder by department_id DESC,salary ASC; 可以使用不在SELECT列表中的列排序。 在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第 一列数据中所有值都是唯一的,将不再对第二列进行排序。 时间字段 date datetime timestamp 插入时间(CURRENT_TIMESTAMP) 不行(now()) 不行(now()) 可以 自动更新(CURRENT_TIMESTAMP) 不行 可以 可以 时区 时间字符串 保存时区 1234567891011121314# 插入的时候,自动插入时间 设置CURRENT_TIMESTAMP--添加CreateTime 设置默认时间 CURRENT_TIMESTAMP ALTER TABLE `test_time` ADD COLUMN `my_time_date` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ;--修改CreateTime 设置默认时间 CURRENT_TIMESTAMP ALTER TABLE `test_time` MODIFY COLUMN `my_time_date` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ; # 更新的时候自动更新时间 设置CURRENT_TIMESTAMP--添加UpdateTime 设置 默认时间 CURRENT_TIMESTAMP 设置更新时间为 ON UPDATE CURRENT_TIMESTAMP ALTER TABLE `test_time` ADD COLUMN `my_time_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间' ;--修改 UpdateTime 设置 默认时间 CURRENT_TIMESTAMP 设置更新时间为 ON UPDATE CURRENT_TIMESTAMP ALTER TABLE `test_time` MODIFY COLUMN `my_time_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间' ; 参考:MySQL 的 timestamp时区问题 时区123456789101112131415161718192021222324252627282930# 查询时区# 不需要看system_time_zone,只需要修改time_zonemysql> show variables like '%time_zone%';+------------------+--------+| Variable_name | Value |+------------------+--------+| system_time_zone | UTC || time_zone | +08:00 |+------------------+--------+2 rows in set (0.01 sec)# 查询全局时区,和会话时区mysql> select @@GLOBAL.time_zone,@@SESSION.time_zone;+--------------------+---------------------+| @@GLOBAL.time_zone | @@SESSION.time_zone |+--------------------+---------------------+| +08:00 | +08:00 |+--------------------+---------------------+1 row in set (0.00 sec)# 设置会话时区set time_zone='+8:00';# 设置全局时区# 全局会话有效。必须重新连接才生效set global time_zone='+8:00;# 修改 mysql 的配置文件永久设置时区[mysqld]default-time-zone=+08:00 mysql当前在什么时区,看哪个变量 看 time_zone,不看 system_time_zone。如要修改时区,直接修改 time_zone,无视 system_time_zone time_zone 的值如果是 SYSTEM 表示什么? 表示跟 system_time_zone 取值一样。安装MySQL后默认就是SYSTEM system_time_zone 的值是怎么来的? 它的值来自mysql服务启动时读取操作系统时区,读取后即使修改操作系统的时区,它的值也不会再改变了,除非重启mysql 服务变量重新读取 system_time_zone 的值能改变吗? 123# 不能通过命令改变mysql> set system_time_zone='JST';ERROR 1238 (HY000): Variable 'system_time_zone' is a read only variable 参考:关于mysql的时区 索引数据结构二叉树二叉树的缺点:顺序插入,会变成一个链表,层级比较深,检索速度慢,可以使用红黑树解决这个问题 1234567891011121314151617181920212223graph TD subgraph Binary Tree 10[10] 10 --> 5[5] 10 --> 15[15] 5 --> 2[2] 5 --> 7[7] 15 --> 12[12] 15 --> 20[20] 2 --> 1[1] 2 --> 3[3] 7 --> 6[6] end subgraph Slash Linked List direction LR L1[1] -->|/| L2[2] L2[2] -->|/| L3[3] L3[3] -->|/| L4[4] L4[4] -->|/| L5[5] L5[5] -->|/| L6[6] end 红黑树红黑树是一个自平衡的二叉树,大数据情况下,层级较深,检索速度慢 1234567891011121314151617181920212223graph TD style 10 fill:#000,stroke:#fff,stroke-width:2px,color:#fff style 5 fill:#f00,stroke:#000,stroke-width:2px,color:#fff style 15 fill:#f00,stroke:#000,stroke-width:2px,color:#fff style 2 fill:#000,stroke:#fff,stroke-width:2px,color:#fff style 7 fill:#000,stroke:#fff,stroke-width:2px,color:#fff style 12 fill:#000,stroke:#fff,stroke-width:2px,color:#fff style 20 fill:#000,stroke:#fff,stroke-width:2px,color:#fff style 1 fill:#f00,stroke:#000,stroke-width:2px,color:#fff style 3 fill:#f00,stroke:#000,stroke-width:2px,color:#fff style 6 fill:#f00,stroke:#000,stroke-width:2px,color:#fff 10[10] 10 --> 5[5] 10 --> 15[15] 5 --> 2[2] 5 --> 7[7] 15 --> 12[12] 15 --> 20[20] 2 --> 1[1] 2 --> 3[3] 7 --> 6[6] B-Tree和B+树的区别 B树:查找时可能在内部节点就能找到所需的值。 B+树:查找时需要遍历到叶子节点才能找到所需的值,因为所有的值都存储在叶子节点中。 范围查询: B树:范围查询需要在树中进行多次查找,并且由于叶子节点之间没有链接,范围查询可能效率较低。 B+树:由于叶子节点形成了一个链表,范围查询可以从一个叶子节点顺序访问到下一个,效率更高。 插入和删除: B树:插入和删除操作可能会影响到所有节点,因为值存储在所有节点中。 B+树:插入和删除操作主要影响叶子节点,内部节点只需要更新键和指针。这种结构使得B+树的插入和删除操作相对简单。 索引覆盖/覆盖索引 select 后面的字段可以从索引中获取到数据,就是索引覆盖,避免回标操作 比如user表,有id,name和age两个字段,id是主键索引,name是普通索引,age没有索引,select age 就是没有使用索引覆盖 如果不符合最左前缀匹配,虽然是索引覆盖,也是无法用到索引,回扫描索引树 索引下推 是5.6之后才有的,默认开启,可以设置index_condition_pushdown=off关闭掉 用类似官网的例子,user表,有id(主键),name,age三个字段,使用name,age建立一个普通索引 1,anthony,18 2,anthony,19 查询select *from user where name='anthony' and age != 18 如果没有使用下推,存储引擎中会查询到 name=’anthony’的数据行,得到行主键索引,比如有两个name=’anthony’,比如第一行和第四行,那么主键id就是1和2,分别用1和2去聚簇索引中查找匹配的行数据,返回给mysql server层,再过滤age!= 18 ,这就会涉及到两次回表,分别是id=1和id=2 如果使用索引下推,直接在存储引擎中通过where的筛选条件,直接在存储引擎中得到行数据,再回表查询,这样就只是需要回标一次,因为只有一行数据是符合name='anthony' and age != 18 使用了索引下推,执行explain计划的时候,extra的会显示Using index condition 回表 主键索引的B+树的叶子节点存储的是整行数据, 非主键索引的B+树的叶子节点存储的是主键的值 当查询根据非聚簇索引查询的时候,会先通过非聚簇索引查询到主键的值,然后再需要通过主键的值再进行一次查询才能得到要查询的数据,这个过程就是回表 主键索引为什么快 explain Possible_key 理论上用到的key 值有可能有多个,也有可能是null key 实际用到的可以 如果值是primary 就是主键索引 row SQL执行过程中会被扫描的行数,该数值越大,意味着需要扫描的行数,相应的耗时更长 事务ACID 原子性:同时成功,或者同时失败,undo log日志, 比如插入一条记录,undo就会保存一条delete日志 一致性:业务代码正确逻辑保证,比如try catch了异常,导致事务不能回滚 隔离性别: 持久性:一旦提交了事务,它对数据库的改变就是应该永久性的,持久性由redo log日志来保证 隔离级别 隔离级别 脏读 不可重复读 幻读 读未提交(Read Uncommitted) ✅ ✅ ✅ mvcc 读已提交(Read Committed) X ✅ ✅ mvcc 可重复读(Repeatable Read) X X ✅ 锁 串行化(Serializable) X X X 读未提交,查询到别的事务修改但是没有提交的数据 不可重复读和幻读都是同一事务类,读取的结果不一样 区别: 不可重复读:别的事务更新操作导致的 幻读,别的事务插入或者删除导致的 数据库准备SQL: 12345678910CREATE TABLE `mytest` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `amount` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;INSERT INTO `lottery`.`mytest` (`id`, `name`, `amount`) VALUES (1, 'anthony', 100.00);INSERT INTO `lottery`.`mytest` (`id`, `name`, `amount`) VALUES (2, 'nick', 200.00); 命令:设置会话登记 123SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;set SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; 演示过程都是,事务A先操作,然后事务B再操作 读未提交读未提交(read-uncommitted),演示一 事务A 事务B anthony.amount=100 1 BEGIN; BEGIN; 2 UPDATE mytest SET amount = amount + 500 WHERE id = 1; 3 BEGIN; SELECT * FROM mytest WHERE id = 1; anthony.amount=600 4 commit; BEGIN; SELECT * FROM mytest WHERE id = 1; anthony.amount=600 读未提交(read-uncommitted),演示二 事务A 事务B anthony.amount=100 1 BEGIN; BEGIN; 2 UPDATE mytest SET amount = amount + 500 WHERE id = 1; 3 SELECT * FROM mytest WHERE id = 1; anthony.amount=600 4 rollback; SELECT * FROM mytest WHERE id = 1; anthony.amount=100 读已提交会话2,在一个事务你,查询到两次不同的金额 事务A 事务B anthony.amount=100 1 BEGIN; BEGIN; 2 UPDATE mytest SET amount = amount + 500 WHERE id = 1; 3 SELECT * FROM mytest WHERE id = 1; anthony.amount=100 4 commit; SELECT * FROM mytest WHERE id = 1; anthony.amount=600 可重复读会话2,在一个事务里,查到的数据是不会变的 事务A 事务B anthony.amount=100 1 BEGIN; 2 SELECT * FROM mytest WHERE id = 1; anthony.amount=100 3 BEGIN; 4 UPDATE mytest SET amount = amount + 500 WHERE id = 1; SELECT * FROM mytest WHERE id = 1; anthony.amount=100 commit; SELECT * FROM mytest WHERE id = 1; anthony.amount=100 commit; 可串行化 事务A 事务B BEGIN; anthony.amount=100 1 UPDATE mytest SET amount = amount + 500 WHERE id = 1; 2 BEGIN; 3 SELECT * FROM mytest WHERE id = 1; 阻塞中 4 commit; SELECT * FROM mytest WHERE id = 1; anthony.amount=150 事务A读操作 事务B写操作 事务B读操作 不阻塞 阻塞 事务B写操作 阻塞 阻塞 可串行化的实现原理: 在不加锁读的操作,会默认加的 读锁-共享锁-S锁:select * from mytest lock in share mode; 读锁是共享的,多个事务可以同时读取同一个资源,但不允许其他事务修改 事务A 事务B 1 Begin; select * from mytest where id =1 lock in share mode; Begin; Update myset set xx=xx where id =1 这里会阻塞 commit; 然后事务B才会执行 写-排它锁-X锁:select * from mytest for update; 写锁是拍他,会阻塞其他的写锁和读锁,update,delete,insert都会加锁 参考 https://learnku.com/articles/40258 https://blog.51cto.com/shijianfeng/2914313 https://www.zhihu.com/question/392569386 https://juejin.cn/post/7136112451959848991 InnoDB12345678910111213141516171819202122232425-- 查看缓存区的大小,单位是字节(Bytes)SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';-- 缓冲池中的总页数:SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_total';-- 已经缓存的页数,需要✖️每一页的大小,通常是16KB每页SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_data';-- 缓冲池中的脏页数:-- 脏页(即已修改但尚未写回磁盘的页)的页数。这也是一个重要的性能指标。-- updat先修改缓存,这时候就成了脏也,然后msyql再开线程更新到磁盘SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';-- 清理binlog日志show variables like '%log_bin%'; #查看binlog启用状态show binary logs; #查看当前配置下已产生的mysql-binlog日志purge master logs before '2023-09-22 00:00:00'; reset master; # 清理过一次,第二天又恢复了-- 关闭binlog[mysqld]skip-log-bin# 然后重启电脑 参考:https://juejin.cn/post/7234924083842220092
Jenkins
Root用户权限启动Jenkins适用于Ubuntu环境下通过apt-get install -y jenkins命令在线安装的Jenkins 1.修改配置文件 123456789vim /etc/default/jenkins# 将下面两个参数修改为root# 修改前JENKINS_USER=$NAMEJENKINS_GROUP=$NAME# 修改后JENKINS_USER=rootJENKINS_GROUP=root 2.更改目录权限 不知道这步有没有起作用 12345cd /var/lib/chown -R root:root ./jenkins# 重启systemctl restart jenkins.service Jenkins使用教程配置JDKManage Jenkins –> Global Tool Configuration 自动安装 手动安装要注意,JAVA_HOME的输入框下面,不要有警告或者错误信息,否则就是路径不正确,取消勾选自动安装 配置Maven 安装Maven Integration 插件 通常自动安装maven就行了,如果手动安装,MAVEN_HOME 输入框下面,不要有警告或者错误信息,否则就是路径不正确 获取当前项目名称在脚本中输入 $JOB_NAME就能获取到了 卸载jenkins12345678910//服务sudo apt-get remove jenkins//安装包,注意这里如果不是ubuntu那就yumsudo apt-get remove --auto-remove jenkins//配置和数据sudo apt-get purge jenkinssudo apt-get purge --auto-remove jenkins 升级jenkins12# 适用于ubuntu安装的apt-get upgrade jenkins 同时构建任务的个数系统管理–>系统设置–>执行者数量 构建成功才继续发包只是个不大不小的功能,很容易忽略了,在 任务的配置–>Post Steps –> Run only if build succeeds 修改时区 WebHook使用的场景,Github Push代码之后,自动构建 第一步.jenkins的配置 第二步.Github的配置 第三步.返回jenkins设置 第四步.push代码,查看有没有正常构建 Jenkins+Docker部署Maven聚合工程安装Jenkins 1234567891011docker run \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(which docker):/usr/bin/docker \ -v /root/jenkins:/var/jenkins_home \ --name jenkins \ --user=root \ -p 8080:8080 \ -p 50000:50000 \ -d \ -u 0 \ jenkins/jenkins:jdk11 第2行是将宿主机的/var/run/docker.sock映射到容器中,这样在容器中运行的docker命令,就会在宿主机上来执行。 第3行是将宿主机的docker程序映射进容器中,这样本身没有安装docker的jenkins容器就可以执行docker命令了(事实上容器里是没有运行docker的服务的,我们只是用这个映射进容器的docker来作为客户端发送docker的指令到/var/run/docker.sock而已,而/var/run/docker.sock已经被链接到宿主机了) Dockerfile 1234FROM openjdk:8-jdk-alpineVOLUME /tmpADD admin-server-0.0.1-SNAPSHOT.jar app.jarENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] Maven的pom.xml配置 12345678910111213141516<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <configuration> <imageName>springboot/${project.artifactId}</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration></plugin> imageName打的镜像名称,这里的镜像名称是:springboot/admin-server dockerDirectory指定docker文件夹的位置 Job配置 • -e “SPRING_PROFILES_ACTIVE=prerelease” ,可以看成是启动jar的时候的,java -jar admin-server.jar –spring.profiles.active=prerelease ,指定运行环境 脚本检测容器的运行1234567891011121314# "=" 两边不能有空格count=`docker ps -a | grep sabong-admin-controlfront |awk '{print $1}'`if [ -n "$count" ]; then docker stop $count docker rm $count echo "停止并删除容器"fidocker run \ -itd \ -p 9011:9011 \ -e “SPRING_PROFILES_ACTIVE=prerelease” \ --name admin-server \ springboot/admin-server 推送镜像到harbor12345678910# 打标签# sabong/sabong-controller-manager:latest 已经build成功了的镜像名字# 10.0.0.7/library/sabong/sabong-controller-manager:latest 新的镜像名字docker tag sabong/sabong-controller-manager:latest 10.0.0.7/library/sabong/sabong-controller-manager:latest# 登录私有仓库docker login -u admin -p 123456 10.0.0.7# 推送镜像docker push 10.0.0.7/library/sabong/sabong-controller-manager:latest Vue打包成镜像123456789101112131415npm installnpm run build:prod# build# sabong/sabong-admin-controlfront 随便起的docker build -t sabong/sabong-admin-controlfront --no-cache . # 打标签docker tag sabong/sabong-admin-controlfront:latest 10.0.0.7/library/sabong/sabong-admin-controlfront:latest# 登录私有仓库docker login -u admin -p 123456 10.0.0.7# 推送镜像docker push 10.0.0.7/library/sabong/sabong-admin-controlfront:latest Dockerfile 123From nginxCOPY dist/ /usr/share/nginx/html/ ⛔ 这里用的是nginx容器里默认的nginx配置文件,所以这里没有使用自定义的nginx配置 SpringBoot项目脚本适用于ssh传输文件,启动脚本 1234567891011121314151617181920#!/bin/bash# 具体不知道是干啥的,加上这个,这个看情况加# BUILD_ID=DONTKILLMEAPP_NAME=xxx.jar# 杀进程pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' ` if [ -n "${pid}" ]; then kill -9 $pidfiecho '准备启动jar包'nohup java -jar /root/$APP_NAME --spring.profiles.active=prod &sleep 3echo '启动成功' Maven多模块打包指定打包项目名 1clean package -pl 模块名 -am 配置SSH server 在系统管理–>System—>SSH Server配置 配置SSH Over FTP publish 这里Verbose output in console的作用是把远程的步骤,和远程的shell执行的结果也打印出来 这里Exec in pty 要勾选,不然项目启动完成了,也不会停止SSH链接 前端打包选择已经配置的node版本 构建环境 Build Steps 选择执行shell 12345npm installnpm run build:prodpwd# 删除上一次构建打的包,然后dist文件夹打包成dist.zip文件rm -f dist.zip && zip -r dist.zip dist 各种问题报错1.HTTP ERROR 403 No valid crumb was included in the request 解决办法:网上都是要去关闭CSRF,很明确的是我这里的全局安全配置里面根本就没有选项,我的版本是jenkins 2.293。所以百度出来的都是一堆垃圾,无奈自己解决,尝试一番之后,找到了方法,如 下图所示:还是在全局安全配置里面,勾选上这个参数即可。 2.Jenkins配置中安装插件时提示No such plugin: cloudbees-folder 1sudo systemctl start jenkins 2.Jenkins和Github personal access token 登录到您的 Jenkins 服务器。 选择“Jenkins”>“Manage Jenkins”>“Configure System”。 滚动到“GitHub”部分。 点击“Add GitHub Server”按钮。 在“API URL”字段中输入您的 Github API URL(例如 api.github.com)。 在“Credentials”字段中选择“Add”。 选择“Kind”为“Username with password”。 在“Username”字段中输入您的 Github 用户名。 在“Password”字段中输入您的 Github 个人访问令牌。 点击“Verify credentials”按钮以验证凭据是否有效。 如果验证成功,请点击“Save”按钮保存更改。 3.jenkins映射docker 12345# 如果docker run jenkins 没有指定# 这里就不能打包,就是因为在jenkins里的容器中,没有安装对象,使用了-v # 就是把jenkins里所需要的docker映射到宿主docker中-v /var/run/docker.sock:/var/run/docker.sock \-v $(which docker):/usr/bin/docker 4.安装插件没有成功 需要到插件中心,在可更新和可选插件里,一个一个手动去搜索安装,如果还有问题,就需要更新jenkins 5.npm install需要权限 1Unable to save binary /var/lib/jenkins/workspace/mymanager-/node_modules/node-sass/vendor/linux-x64-83 : Error: EACCES: permission denied, mkdir '/var/lib/jenkins/workspace/lottery-web-24kai-ausk3/node_modules/node-sass/vendor' 修改端口123456789101112131415161718192021222324252627282930# 第一步sudo vim /etc/init.d/jenkins# 8088改成想要的check_tcp_port "http" "$HTTP_PORT" "8088" || return 1# 第二步sudo vim /etc/default/jenkins# 8088改成想要的HTTP_PORT=8088# 第三步vim /lib/systemd/system/jenkins.serviceEnvironment="JENKINS_PORT=80"# 执行sudo systemctl daemon-reloadsudo systemctl start jenkinssudo systemctl status jenkins# 这个时候就启动报错,然后接着修改vim /lib/systemd/system/jenkins.service# 本来是jenkins的,改成rootUser=rootGroup=root# 执行,就可以了,不知道为啥sudo systemctl daemon-reloadsudo systemctl start jenkinssudo systemctl status jenkins jenkins使用root账号登录设置1 设置2 权限管理1.安装插件,Role-based Authorization Strategy 2.点击 管理系统–>安全段落下的–>全局安全配置,选中 3.管理系统–>安全段落下的 就会多一个功能