1.脚本入参
SET NGINX_DIR=C:\Zone\nginx-1.21.4\nginx-1.21.4\
该路径配置成nginx的根目录文件夹
2.Nginx管理脚本
==================================================== @echo off chcp 65001 color 0a rem 当前bat的作用 echo ==================begin======================== cls SET NGINX_DIR=C:\Zone\nginx-1.21.4\nginx-1.21.4\ color 0a TITLE Nginx 管理程序控制面板 CLS ECHO. ECHO. * Nginx 管理程序 * ECHO. :MENU ECHO. * nginx 进程list * tasklist|findstr /i "nginx.exe" ECHO. ECHO. [1] 启动Nginx ECHO. [2] 关闭Nginx ECHO. [3] 重启Nginx ECHO. [4] 退 出 ECHO. ECHO.请输入选择项目的序号: set /p ID= IF "%id%"=="1" GOTO start IF "%id%"=="2" GOTO stop IF "%id%"=="3" GOTO restart IF "%id%"=="4" EXIT PAUSE :start call :startNginx GOTO MENU :stop call :shutdownNginx GOTO MENU :restart call :shutdownNginx call :startNginx GOTO MENU :shutdownNginx ECHO. ECHO.关闭Nginx...... taskkill /F /IM nginx.exe > nul ECHO.OK,关闭所有nginx 进程 goto :eof :startNginx ECHO. ECHO.启动Nginx...... IF NOT EXIST "%NGINX_DIR%nginx.exe" ECHO "%NGINX_DIR%nginx.exe"不存在 cd "%NGINX_DIR%" IF EXIST "%NGINX_DIR%nginx.exe" ( echo "start '' nginx.exe" start "" nginx.exe ) ECHO.OK goto :eof
3.Nginx重启脚本
@echo off SET NGINX_DIR=%~dp0 chcp 65001 color 0a ECHO.关闭Nginx...... taskkill /F /IM nginx.exe > nul ECHO.OK,关闭所有nginx 进程 ECHO. ECHO.当前Nginx路径%NGINX_DIR% ,启动Nginx...... IF NOT EXIST "%NGINX_DIR%\nginx.exe" ECHO "%NGINX_DIR%\nginx.exe"不存在 cd "%NGINX_DIR%" IF EXIST "%NGINX_DIR%\nginx.exe" ( echo "start '' nginx.exe" start "" nginx.exe ) ECHO.OK 启动成功 pause;
微信小程序连接蓝牙工具类支持IOS和安卓
// 初始化蓝牙(判断用户有没有开蓝牙) --> 搜索蓝牙 --> 连接蓝牙 --> 根据连接的deviceId获取服务serviceUUID --> // 根据服务serviceUUID获取特征值 --> 根据特征值获取 读写权限 --> 根据读写 数据交互 var test = 'FE08010000000000000108'; var ble={ //适配器开启状态 openBluetoothAdapter:false, //蓝牙是否可用 available:false, //服务发现是否开启 discovering:false, //发现的设备列表 deviceList:[], //当前连接设备id connectingDeviceId:'', //服务uuid services_UUID:'', //特征值uuid characteristic_UUID:'', } //蓝牙方法 // 初始化蓝牙 ble.openEvent = () => { wx.getLocation({ type: 'gcj02', //返回可以用于wx.openLocation的经纬度 success: function (res) { // let latitude = res.latitude //维度 // let longitude = res.longitude //经度 console.log(res); } }); openBluetooth(); } // 搜索蓝牙 ble.searchEvent = () => { if (ble.discovering){ toast('正在搜索'); return; } ble.deviceList= [] // 停止搜寻附近的蓝牙外围设备 stopDiscovery(); // 获取本机蓝牙适配器状态 if(getBluetoothState()){ return; } // 监听蓝牙适配器状态变化事件 onBluetoothStateChange(); // 开始搜寻附近的蓝牙外\围设备 startDiscovery(); // 监听寻找到新设备 onFoundBluetooth(); } // 连接设备 ble.connectEvent = function(deviceId, successCallback,errorCallback){ if(this.data.connected){ return; } // 停止搜寻附近的蓝牙外围设备 stopDiscovery(); // 断开与低功耗蓝牙设备的连接 然后再连接新的设备 closeConnection(deviceId); // 连接低功耗蓝牙设备 BLEConnection(deviceId); } //蓝牙发送数据 ble.sendMsg = function(msg, successCallback,errorCallback){ this.writeToBluetoothValue(ble.connectingDeviceId,ble.services_UUID,ble.characteristic_UUID,msg,successCallback,errorCallback); } //========================================= //依赖方法 // 初始化蓝牙模块 function openBluetooth(){ wx.openBluetoothAdapter({ success(e){ if (e.errMsg == 'openBluetoothAdapter:ok'){ ble.openBluetoothAdapter = true; getBluetoothState(); } }, fail(){ wx.showModal({ title: '温馨提示', content: '请检查手机蓝牙是否开启', showCancel:false }); ble.openBluetoothAdapter = false; }, }) } // 获取本机蓝牙适配器状态 function getBluetoothState(){ wx.getBluetoothAdapterState({ success(e){ ble.available=e.available ble.discovering=e.discovering return true; }, fail(){ ble.available=false ble.discovering=false return false; } }); } // 停止搜寻附近的蓝牙外围设备 function stopDiscovery(){ wx.stopBluetoothDevicesDiscovery({ success(res){ console.log('停止搜寻附近的蓝牙外围设备'); console.log(res); ble.discovering = false }, fail(){ toast('停止搜索失败'); }, }); } // 监听蓝牙适配器状态变化事件 function onBluetoothStateChange(){ wx.onBluetoothAdapterStateChange(function(res){ ble.available = res.available ble.discovering = res.discovering }); } // 开始搜寻附近的蓝牙外围设备 function startDiscovery(){ console.log('开始搜索设备'); wx.startBluetoothDevicesDiscovery({ success (res) { ble.discovering = res.isDiscovering // that.getDevices(); }, fail(){ ble.discovering = false toast('搜索失败'); } }) } // 监听寻找到新设备的事件 function onFoundBluetooth(){ wx.onBluetoothDeviceFound(function (res) { // that.getDevices(); // 兼容安卓及iOS设备 if(res.deviceId){ that.devicesData(res); } else if(res.devices){ that.devicesData(res.devices[0]); } else if(res[0]){ that.devicesData(res[0]); } }); } // 获取在蓝牙模块生效期间所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备 function getDevices(){ wx.getBluetoothDevices({ success: function (res) { console.log('获取在蓝牙模块生效期间所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备'); console.log(res); ble.deviceList = res.devices; } }) } // 断开与低功耗蓝牙设备的连接 function closeConnection(){ let connectingDeviceId = ble.connectingDeviceId; if(!connectingDeviceId){ return; } wx.closeBLEConnection({ deviceId: connectingDeviceId, success(res){ console.log('断开与低功耗蓝牙设备的连接'); console.log(res); }, fail(){ toast('断开连接失败'); } }); } // 连接低功耗蓝牙设备 function BLEConnection(deviceId){ loading('连接中'); console.log('连接中...'); console.log(deviceId); wx.createBLEConnection({ deviceId: deviceId, timeout: 60000, success(res){ console.log('连接成功'); console.log(res); // connectingDeviceId = deviceId; ble.connected = true; ble.connectingDeviceId = deviceId getServices(deviceId); hide_Loading(); toast('连接成功'); }, fail(res){ console.log('连接失败'); console.log(res); ble.connected = false; hide_Loading(); }, }); } // 获取蓝牙设备所有服务(service) 为了获取service的UUID function getServices(deviceId){ // console.log(deviceId); wx.getBLEDeviceServices({ deviceId:deviceId, success(res){ // console.log('获取蓝牙设备service'); console.log(res); ble.services = res.services let uuid = res.services; let len = uuid.length; for(let i = 0; i < len; i++){ // if (res.services[i].isPrimary) { getCharacteristics(deviceId,res.services[i].uuid); } }, fail(res){ toast('获取服务失败'); console.log(res); }, }); } // 获取蓝牙设备某个服务中所有特征值(characteristic) 为了该特征值UUID支持的操作类型 function getCharacteristics(deviceId,servicesId){ wx.getBLEDeviceCharacteristics({ deviceId:deviceId, serviceId:servicesId, success(res){ console.log('获取蓝牙设备characteristic'); console.log(res); if(res.errCode === 0){ let characteristics = res.characteristics; let len = characteristics.length; for(let k = 0; k < len; k++){ let indicate = characteristics[k].properties.indicate; let notify = characteristics[k].properties.notify; let read = characteristics[k].properties.read; let write = characteristics[k].properties.write; console.log(indicate,notify,read,write); if(indicate && notify && read && write){ // let connectingDeviceId = res.deviceId; let connectingDeviceId = deviceId; console.log('connectingDeviceId'); console.log(connectingDeviceId); // let services_UUID = res.serviceId; let services_UUID = servicesId; console.log('services_UUID'); console.log(services_UUID); let characteristic_UUID = characteristics[k].uuid; console.log('characteristic_UUID'); console.log(characteristic_UUID); ble.connectingDeviceId = connectingDeviceId; ble.services_UUID = services_UUID ble.characteristic_UUID = characteristic_UUID notifyValueChange(connectingDeviceId,services_UUID,characteristic_UUID); } } } }, fail(){ toast('获取特征值失败'); } }); } // 启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值 function notifyValueChange(deviceId,services_UUID,characteristic_UUID){ wx.notifyBLECharacteristicValueChange({ deviceId:deviceId, serviceId:services_UUID, characteristicId:characteristic_UUID, state:true, success(res){ console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值: 成功---'); console.log(res); onValueChange(); // setTimeout(function () { // let connectingDeviceId = that.data.connectingDeviceId; // let services_UUID = that.data.services_UUID; // let characteristic_UUID = that.data.characteristic_UUID; // writeToBluetoothValue(connectingDeviceId,services_UUID,characteristic_UUID,test); // },1000); }, fail(res){ console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值: 失败---'); console.log(res); }, }); } // 监听低功耗蓝牙设备的特征值变化 // 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。 function onValueChange(){ wx.onBLECharacteristicValueChange(function(res){ console.log('监听低功耗蓝牙设备的特征值变化'); console.log(res); console.log(ab2hex(res.value)); // 获取设备返回的数据 let hex = ab2hex(res.value); // 获取总次数 let num = hexSlice(hex); console.log(num) ble.shakeNum = num }); } // 蓝牙写数据 function writeToBluetoothValue(deviceId,services_UUID,characteristic_UUID,buffer,successCallback,errorCallback){ let value = hex2ab(buffer); wx.writeBLECharacteristicValue({ deviceId:deviceId, serviceId:services_UUID, characteristicId:characteristic_UUID, value:value, success(res){ console.log('向低功耗蓝牙设备特征值中写入二进制数据: 成功---'); console.log(res); successCallback(res) }, fail(res){ console.log('向低功耗蓝牙设备特征值中写入二进制数据: 失败---'); console.log(res); errorCallback(res) } }) } // 读取低功耗蓝牙设备的特征值的二进制数据值 // 接口读取到的信息需要在 onBLECharacteristicValueChange 方法注册的回调中获取 function readValue(){ let connectingDeviceId = this.data.connectingDeviceId; let services_UUID = this.data.services_UUID; let characteristic_UUID = this.data.characteristic_UUID; wx.readBLECharacteristicValue({ deviceId:connectingDeviceId, serviceId:services_UUID, characteristicId:characteristic_UUID, success(res){ console.log('读取低功耗蓝牙设备的特征值的二进制数据值: 成功---'); console.log(res); }, fail(res){ console.log('读取低功耗蓝牙设备的特征值的二进制数据值: 失败---'); console.log(res); } }); } //========================================= //工具函数 // ArrayBuffer转16进度字符串示例 function ab2hex(buffer) { let hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2); } ); return hexArr.join(''); } /** * 16进制字符串转ArrayBuffer */ function hex2ab(str) { if (!str) { return new ArrayBuffer(0); } let typedArray = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function (h) { return parseInt(h, 16) })); let buffer1 = typedArray.buffer; console.log(buffer1); return buffer1; } // 16进制字符串取需要的字节(fe 08 01 00 01 01 01 7a0b 008f) function hexSlice(hex) { // 取k8位 let k8 = hex.slice(14,16); //取k9位 let k9 = hex.slice(16,18); return parseInt(k9+k8,16); } function toast(title) { wx.showToast({ title: title, icon:'none', duration:1500, success(){ setTimeout(()=>{ wx.hideToast(); },2000); } }); } function loading(title) { wx.showLoading({ title:title, mask:true, }); } function hide_Loading() { wx.hideLoading(); } //拼接新的device function devicesData(new_devices){ let deviceList = ble.deviceList; let len = deviceList.length; let isExist = false; console.log(new_devices); if(!new_devices.name){ new_devices.name = '空'; return; } let advertisData = ab2hex(new_devices.advertisData); if(!advertisData){ advertisData = '空'; } new_devices.advertisData = advertisData; for(let i = 0; i < len; i++){ if(new_devices.deviceId == deviceList[i].deviceId){ isExist = true; deviceList.splice(i,1,new_devices); } } if(!isExist){ deviceList.push(new_devices); } ble.deviceList = deviceList }
小程序地图转百度地图坐标
1.JAVA的方式
public class MapConvertUtil { /** * 坐标转换,腾讯地图坐标转换成百度地图坐标 * @param lat 腾讯纬度 * @param lon 腾讯经度 * @return 返回结果:经度,纬度 */ public static double[] qqToBaidu(double lat, double lon){ double bd_lat; double bd_lon; double x_pi=3.14159265358979324; double x = lon, y = lat; double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); bd_lon = z * Math.cos(theta) + 0.0065; bd_lat = z * Math.sin(theta) + 0.006; System.out.println("bd_lat:"+bd_lat); System.out.println("bd_lon:"+bd_lon); return new double[]{bd_lat,bd_lon}; } /** * 坐标转换,百度地图坐标转换成腾讯地图坐标 * @param lat 百度坐标纬度 * @param lon 百度坐标经度 * @return 返回结果:纬度,经度 */ public static double[] baiduToQq(double lat, double lon){ double tx_lat; double tx_lon; double x_pi=3.14159265358979324; double x = lon - 0.0065, y = lat - 0.006; double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); tx_lon = z * Math.cos(theta); tx_lat = z * Math.sin(theta); return new double[]{tx_lat,tx_lon}; } }
2.js方式
//腾讯地图坐标转百度地图坐标 qqToBaidu(lng, lat) { if (lng == null || lng == '' || lat == null || lat == '') return [lng, lat]; var x_pi = 3.14159265358979324; var x = parseFloat(lng); var y = parseFloat(lat); var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); var lng = (z * Math.cos(theta) + 0.0065).toFixed(8); var lat = (z * Math.sin(theta) + 0.006).toFixed(8); return [lng, lat]; },
Tar切分压缩解压缩
1.压缩
tar cvzf - ./Data | split -d -b 800m - Data.tar.gz
2.解压缩
cat Data.tar.gz* | tar zvxf -
Docker Redis远程主机强迫关闭了一个现有的连接
使用Docker安装的redis,springboot连接redis,经常过一段时间就从redis取值失败,报这个错误Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
1. 报错原因
spring中配置的超时时间应该大于tcp的存活时间,否则tcp连接还存活着,spring以为已经超时,又去创建,就会强制之前的连接关闭。
2.解决方案
修改redis.conf文件中的tcp-keepalive数值。就是一次连接tcp的存活时间
但是通过reids安装的有时候配置文件可能会不生效,所以使用docker重装redis,确保配置文件可以生效
修改springboot 连接redis的超时时间,需要这个时间大于tcp-keepalive的时间
3.重装Redis确保配置文件生效
拉取最新镜像
docker pull redis
创建文件夹
cd /home mkdir redis/conf mkdir redis/data
写入redis配置文件。redis.conf
1. cd /home/redis/conf 2. vim redis.conf
配置文件内容
##节点端口 port 6379 ##允许任何来源 #bind 0.0.0.0 bind 47.99.149.92 120.244.10.31 ## 是为了禁止公网访问redis cache,加强redis安全的。它启用的条件,有两个:1) 没有bind IP 2) 没有设置访问密码 启用后只能够通过lookback ip(127.0.0.1)访问Redis cache,如果从外网访问,则会返回相应的错误信息 protected-mode no ##开启持久化模式 appendonly yes appendfilename appendonly.aof #开启混合持久化 aof-use-rdb-preamble yes # 文件达到1m时进行重写,然后如果文件大小增长了一倍,也会触发重写。 auto-aof-rewrite-min-size 1mb auto-aof-rewrite-percentage 100 ##AOF 文件和 Redis 命令是同步频率的,假设配置为 always,其含义为当 Redis 执行命令的时候,则同时同步到 AOF 文件,这样会使得 Redis 同步刷新 AOF 文件,造成缓慢。而采用 evarysec 则代表 ## 每秒同步一次命令到 AOF 文件。 appendfsync everysec #pidfile redis.pid #进程pid文件,加port以示区分 pidfile /data/redis/data/redis_6379.pid # 后台运行 ---- docker中使用后台运行将无法启动容器(应该是容器无法检测后台运行进程) # daemonize yes databases 20 tcp-keepalive 20 #redis初始密码 requirepass 1234
启动容器
1. 2. docker run -d -p 6379:6379 --name my_redis --privileged=true -v /home/redis/conf/red
通过这种方式可以指定redis的配置文件,确保配置文件中的tcp-keepalive生效
4. 配置springboot连接redis
##redis配置 spring.redis.database=0 ### 服务器地址,默认为localhost spring.redis.host=172.1.1.1 ### 链接端口,默认为6379 spring.redis.port=6379 ### redis密码默认为空 spring.redis.password=123456 #处理连接超时等 如 java.io.IOException: 远程主机强迫关闭了一个现有的连接。 #Spring Boot 从 2.0版本开始,将默认的Redis客户端Jedis替换为Lettuce spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.max-idle=5 spring.redis.lettuce.pool.min-idle=0 spring.redis.timeout=30000ms # 关闭超时时间 spring.redis.lettuce.shutdown-timeout=100