natapp国内高速内网穿透服务

1、什么是内网穿透

内网穿透用通俗的语言讲,就是如何让外部的人员或服务访问我们我们局域网的服务的过程,称之为内网穿透。

2、natapp就是一款提供内网穿透的服务

服务器更新:全面支持HTTPS协议以及本地SSL证书,支持WSS协议.同时支持HTTP/2 WEB协议,支持微信小程序本地开发.
全面自动支持泛子域名与访客真实IP地址.
网址 :https://natapp.cn

3、内网穿透可以做什么?

1. 上文举例的办公软件

2. 放在家里的树莓派,服务器等,需要远程ssh管理,这样打通服务器的22端口即可远程通过ssh操作服务器了.

3. 微信/支付宝等本地开发.现在微信/支付宝等应用,需要服务器接收微信/支付宝发送的回调信息,然而在本地开发程序的话,还得实时上传到服务器,以便支持微信/支付宝的回调信息,如果使用了natapp内网穿透软件,将回调地址设置成natapp提供的地址,回调数据立即传递回本地,,这样很方便的在本地就可以实时调试程序,无须再不断上传服务器等繁琐且无意义的步骤.

4. 一些企业内部数据库,由于安全等原因,不愿意放到云服务器上,可以将数据库放到办公室本地,然后通过natapp的tcp隧道映射,这样既保证安全,又保证公网可以正常访问.

5. 一些开发板做的监控等信息,每台设备运行一条隧道,可以方便的管理监控各个设备的运行情况.

6. 一些本地运行的游戏,想和好基友一起联网玩,一条命令运行natapp即可实现联网游戏.

7. 群辉上运行natapp之后,随时随地在任何地方可以访问到群辉上应用

4、内网穿透安全吗?

现在服务器被黑的情况,多半是服务器上一些软件/漏洞/端口导致的.你的应用如果放在公网服务器,由于缺少系统安全维护知识,会变得很危险.而用了natapp内网穿透软件之后,将服务器放在本地,暴露给公网的也仅仅是应用层面的一个端口,其他系统上的漏洞/端口都被隐藏起来.从这个层面来说,提高了很多安全性.

当然,你的应用本身带来的安全性,比如代码本身有漏洞,如果是映射数据库应用,数据库弱密码等,这需要引起重视,排查映射的应用本身安全性即可.

Natapp本身的隧道传输采用ssl256位加密,这种加密安全性现阶段完全无法破解,natapp隧道的安全性无需考虑

yansongda/pay 优雅的php Alipay/WeChat/Unipay 的支付 SDK 扩展

开发了多次支付宝与微信支付后,很自然产生一种反感,惰性又来了,想在网上找相关的轮子,可是一直没有找到一款自己觉得逞心如意的,要么使用起来太难理解,要么文件结构太杂乱,只有自己撸起袖子干了。

特点

  • 多租户支持
  • Swoole 支持
  • 灵活的插件机制
  • 丰富的事件系统
  • 命名不那么乱七八糟
  • 隐藏开发者不需要关注的细节
  • 根据支付宝、微信最新 API 开发而成
  • 高度抽象的类,免去各种拼json与xml的痛苦
  • 文件结构清晰易理解,可以随心所欲添加本项目中没有的支付网关
  • 方法使用更优雅,不必再去研究那些奇怪的的方法名或者类名是做啥用的
  • 内置自动获取微信公共证书方法,再也不用再费劲去考虑第一次获取证书的的问题了
  • 符合 PSR2、PSR3、PSR4、PSR7、PSR11、PSR14、PSR18 等各项标准,你可以各种方便的与你的框架集成

安装
# yansongda/pay 2.x

composer require "larva/laravel-transaction:^2.0"

# yansongda/pay 3.x

composer require "larva/laravel-transaction:^3.0"

laravel 用户

配置文件

php artisan vendor:publish --provider="Yansongda\LaravelPay\PayServiceProvider" --tag=laravel-pay

lumen 用户

配置文件

请手动复制配置文件

service provider

$app->register(Yansongda\LaravelPay\PayServiceProvider::class);

支持的支付方法

1、支付宝

  • 电脑支付
  • 手机网站支付
  • APP 支付
  • 刷卡支付
  • 扫码支付
  • 账户转账
method 描述
web 电脑支付
wap 手机网站支付
app APP 支付
pos 刷卡支付
scan 扫码支付
transfer 帐户转账

2、微信

  • 公众号支付
  • 小程序支付
  • H5 支付
  • 扫码支付
  • 刷卡支付
  • APP 支付
  • 企业付款
  • 普通红包
  • 分裂红包

method描述mp公众号支付miniapp小程序支付wapH5 支付scan扫码支付pos刷卡支付appAPP 支付transfer企业付款redpack普通红包groupRedpack分裂红包

版本支持

版本 PHP 分支 状态
v3.5 >= 8.0 master 积极开发中
v3.4 >= 8.0 master EOL,停止维护
v3.0-3.3 >= 7.3 master EOL,停止维护
v2.x >= 7.0 v2 安全支持,不做新功能开发
v1.x >= 5.6 v1 EOL,停止维护

官网:https://pay.yansongda.cn/

 

ThinkPHP8.0搭建的后台管理系统EasyAdmin8

项目介绍

EasyAdmin8在EasyAdmin的基础上,使用ThinkPHP v8.0重构,并且开发了Laravel v10.20和webman等框架的版本,是市面上常用框架的快速开发后台管理系统。

官网链接:https://easyadmin8.top/

项目特性

快速CURD命令行
一键生成控制器、模型、视图、JS文件
支持关联查询、字段预设置等等
基于auth的权限管理系统
通过注解方式来实现auth权限节点管理
具备一键更新auth权限节点,无需手动输入管理
完善的后端权限验证以及前面页面按钮显示、隐藏控制
完善的菜单管理
分模块管理
无限极菜单
菜单编辑会提示权限节点
完善的前端组件功能
对layui的form表单重新封装,无需手动拼接数据请求
简单好用的图片、文件上传组件
简单好用的富文本编辑器ckeditor
对弹出层进行再次封装,以极简的方式使用
对table表格再次封装,在使用上更加舒服
根据table的cols参数再次进行封装,提供接口实现image、switch、list等功能,再次基础上可以自己再次扩展
根据table参数一键生成搜索表单,无需自己编写
完善的后台操作日志
记录用户的详细操作信息
按月份进行分表记录
上传文件记录管理
后台路径自定义,防止别人找到对应的后台地址

项目简介

EasyAdmin8 在 EasyAdmin 的基础上更新 ThinkPHP 框架到 8.0 ,PHP 最低版本要求不低于 8.0
ThinkPHP v8.0 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:
https://github.com/wolf-leo/EasyAdmin8

https://gitee.com/wolf18/easyAdmin8
EasyAdmin8-Laravel 在 EasyAdmin 的基础上使用 Laravel 10.x 重构,PHP 最低版本要求不低于 8.1
Laravel v10.x 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:

https://github.com/wolf-leo/EasyAdmin8-Laravel

https://gitee.com/wolf18/EasyAdmin8-Laravel
EasyAdmin8-webman 在 EasyAdmin 的基础上使用 webman 最新版重构,PHP 最低版本要求不低于 8.0
webman 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:

https://github.com/wolf-leo/EasyAdmin8-webman

https://gitee.com/wolf18/EasyAdmin8-webman

特别感谢
以下项目排名不分先后

EasyAdmin: https://github.com/zhongshaofa/easyadmin

ThinkPHP:https://github.com/top-think/framework

Laravel:https://laravel.com/docs/10.x

webman:https://github.com/walkor/webman

Layuimini:https://github.com/zhongshaofa/layuimini

Annotations:https://github.com/doctrine/annotations

Layui:https://github.com/sentsin/layui

Jquery:https://github.com/jquery/jquery

RequireJs:https://github.com/requirejs/requirejs

WangEditor:https://github.com/wangfupeng1988/wangEditor

Echarts:https://github.com/apache/incubator-echarts

BUG反馈
项目使用过程成,如遇到BUG,请到各版本的Gitee中的issue进行提问!

版权信息
EasyAdmin8遵循EasyAdmin的MIT开源协议发布,并提供免费使用。

换脸roop部署cpu和gpu模式

roop 介绍

上面介绍的一键换脸项目叫做Roop,项目官方介绍如下:你只需要一张所需脸部的图像,没有数据集,无需训练,你就可以将拍摄视频其中的面孔替换为你选择的面孔。该工具旨在为快速发展的人工智能生成媒体行业做出富有成效的贡献,它将帮助艺术家完成诸如动画自定义角色或使用角色作为服装模型等任务。本地安装Roop,官方给出了2种选择,基于CPU安装或者基于GPU安装。

1.roop是新开源了一个单图就可以进行视频换脸的项目,只需要一张所需面部的图像。不需要数据集,不需要训练。

2.大概的测试了一下,正脸换脸效果还不错,融合也比较自然。但如果人脸比较大,最终换出的效果可能会有些模糊。侧脸部分的幅度不宜过大,否则会出现人脸乱飘的情况。在多人场景下,也容易出现混乱。

3.使用简单,在处理单人视频和单人图像还是的换脸效果还是可以的,融合得也不错,适合制作一些小视频或单人图像。

roop 安装

获取代码,

sudo apt install git -y
git clone --depth 1 https://github.com/s0md3v/roop.git

安装依赖,

cd roop
pip install -r requirements.txt

# 如遇错误,可依提示。例如:
#  pip install -r requirements.txt --use-pep517
# 如遇 dependency conflict,可修改依赖版本。例如:
#  numpy>=1.23.5

# 若配置镜像
pip config set global.index-url http://mirrors.aliyun.com/pypi/simple
pip config set install.trusted-host mirrors.aliyun.com
cat ~/.config/pip/pip.conf

其实到这里就可以直接运行如下代码进行视频换脸了,首次启动会下载529M的模型文件,目前使用的是CPU,如果你显卡不高不想折腾了的话可以开始体验了。但是我们继续折腾,去开启GPU显卡处理功能。

python run.py

安装CUDA

(1)这是NVIDIA显卡的操作步骤,其它显卡用不了,打开链接:https://developer.nvidia.com/cuda-11-8-0-download-archive,安装程序下载下来之后,直接双击运行安装即可,安装选项选择精简版,安装完成关闭窗口即可。

(2)安装依赖

还在打开Python虚拟环境的cmd窗口中依次输入如下命令并回车,安装依赖,一条命令执行完再运行下一条命令。

pip uninstall onnxruntime onnxruntime-gpu
pip install onnxruntime-gpu

然后再输入如下命令即可启动roop操作窗口进行视频换脸了,

python run.py –execution-provider cuda
左侧点击select a face按钮选择一张待使用的人脸,右侧按钮select a target选择待转换的视频,点击start按钮会提示选择输出视频路径,选择完毕后即可开始转换。

roop运行常用指令
只用CPU处理视频:python run.py
使用GPU处理视频:python run.py –execution-provider cuda
图片保存jpg格式 python run.py –execution-provider cuda –temp-frame-format jpg
视频高清化处理: python run.py –execution-provider cuda –temp-frame-format jpg –frame-processor face_swapper face_enhancer
处理脸部跳闪: python run.py –execution-provider cuda –temp-frame-format jpg –frame-processor face_swapper face_enhancer –similar-face-distance 1.5
指定帧识别人脸并替换:python run.py –execution-provider cuda –reference-face-position 3 –reference-frame-number 166 –similar-face-distance 1.5
其他参数
–temp-frame-format {jpg,png} 用于帧提取的图像格式
–temp-frame-quality [0-100] 用于帧提取的图像质量
–output-video-encoder {libx264,libx265,libvpx-vp9,h264_nvenc,hevc_nvenc} 用于输出视频的编码器
–output-video-quality [0-100] 用于输出视频的质量
–max-memory MAX_MEMORY 最大RAM量(单位:GB)
–execution-threads EXECUTION_THREADS 执行线程数量

python中requirements.txt的生成与使用

在导入一个新项目的时候往往需要下载安装很多依赖,这时如果只是一个个下载非常繁琐,好在很多代码中都附带有requirements.txt文件,可以很方便的安装相应依赖,下面记录一下如何使用与生成该文件。

使用

激活项目具体使用的环境,切换到requirements.txt目录下执行该命令即可。

pip install -r requirements.txt

生成

方式一

生成的是该环境中所有的依赖包,对于想要获得该环境中的某个项目的依赖不友好。

pip freeze > requirements.txt 
# 在当前路径下生成,或者可以指定生成路径如 E:\requirements.txt

方式二

直接获得某个项目的依赖包,但需要另外安装包pipreqs。

# 当前环境下直接安装 
pip install pipreqs

利用该包可以完成对项目依赖包的获取。

# 切换到项目根目录下执行命令 
pipreqs ./ --encoding=utf8 
# 如果当前路径下已经存在requirements.txt文件,会提示附加上--force 
pipreqs ./ --encoding=utf8 --force

Golang经典校验库validator用法解析

一、概述

在接口开发经常会遇到一个问题是后端需要写大量的繁琐代码进行数据校验,所以就想着有没有像前端校验一样写规则进行匹配校验,然后就发现了validator包,一个比较强大的校验工具包下面是一些学习总结,详细内容可以查看validator

二、操作符说明

标记 标记说明
, 多操作符分割
| 或操作
跳过字段验证

三、常用标记说明

标记 标记说明
required 必填 Field或Struct validate:"required"
omitempty 空时忽略 Field或Struct validate:"omitempty"
len 长度 Field validate:"len=0"
eq 等于 Field validate:"eq=0"
gt 大于 Field validate:"gt=0"
gte 大于等于 Field validate:"gte=0"
lt 小于 Field validate:"lt=0"
lte 小于等于 Field validate:"lte=0"
eqfield 同一结构体字段相等 Field validate:"eqfield=Field2"
nefield 同一结构体字段不相等 Field validate:"nefield=Field2"
gtfield 大于同一结构体字段 Field validate:"gtfield=Field2"
gtefield 大于等于同一结构体字段 Field validate:"gtefield=Field2"
ltfield 小于同一结构体字段 Field validate:"ltfield=Field2"
ltefield 小于等于同一结构体字段 Field validate:"ltefield=Field2"
eqcsfield 跨不同结构体字段相等 Struct1.Field validate:"eqcsfield=Struct2.Field2"
necsfield 跨不同结构体字段不相等 Struct1.Field validate:"necsfield=Struct2.Field2"
gtcsfield 大于跨不同结构体字段 Struct1.Field validate:"gtcsfield=Struct2.Field2"
gtecsfield 大于等于跨不同结构体字段 Struct1.Field validate:"gtecsfield=Struct2.Field2"
ltcsfield 小于跨不同结构体字段 Struct1.Field validate:"ltcsfield=Struct2.Field2"
ltecsfield 小于等于跨不同结构体字段 Struct1.Field validate:"ltecsfield=Struct2.Field2"
min 最小值 Field validate:"min=1"
max 最大值 Field validate:"max=2"
structonly 仅验证结构体,不验证任何结构体字段 Struct validate:"structonly"
nostructlevel 不运行任何结构级别的验证 Struct validate:"nostructlevel"
dive 向下延伸验证,多层向下需要多个dive标记 [][]string validate:"gt=0,dive,len=1,dive,required"
dive Keys & EndKeys 与dive同时使用,用于对map对象的键的和值的验证,keys为键,endkeys为值 map[string]string validate:"gt=0,dive,keys,eq=1|eq=2,endkeys,required"
required_with 其他字段其中一个不为空且当前字段不为空 Field validate:"required_with=Field1 Field2"
required_with_all 其他所有字段不为空且当前字段不为空 Field validate:"required_with_all=Field1 Field2"
required_without 其他字段其中一个为空且当前字段不为空 Field `validate:”required_without=Field1 Field2″
required_without_all 其他所有字段为空且当前字段不为空 Field validate:"required_without_all=Field1 Field2"
isdefault 是默认值 Field validate:"isdefault=0"
oneof 其中之一 Field validate:"oneof=5 7 9"
containsfield 字段包含另一个字段 Field validate:"containsfield=Field2"
excludesfield 字段不包含另一个字段 Field validate:"excludesfield=Field2"
unique 是否唯一,通常用于切片或结构体 Field validate:"unique"
alphanum 字符串值是否只包含 ASCII 字母数字字符 Field validate:"alphanum"
alphaunicode 字符串值是否只包含 unicode 字符 Field validate:"alphaunicode"
alphanumunicode 字符串值是否只包含 unicode 字母数字字符 Field validate:"alphanumunicode"
numeric 字符串值是否包含基本的数值 Field validate:"numeric"
hexadecimal 字符串值是否包含有效的十六进制 Field validate:"hexadecimal"
hexcolor 字符串值是否包含有效的十六进制颜色 Field validate:"hexcolor"
lowercase 符串值是否只包含小写字符 Field validate:"lowercase"
uppercase 符串值是否只包含大写字符 Field validate:"uppercase"
email 字符串值包含一个有效的电子邮件 Field validate:"email"
json 字符串值是否为有效的 JSON Field validate:"json"
file 符串值是否包含有效的文件路径,以及该文件是否存在于计算机上 Field validate:"file"
url 符串值是否包含有效的 url Field validate:"url"
uri 符串值是否包含有效的 uri Field validate:"uri"
base64 字符串值是否包含有效的 base64值 Field validate:"base64"
contains 字符串值包含子字符串值 Field validate:"contains=@"
containsany 字符串值包含子字符串值中的任何字符 Field validate:"containsany=abc"
containsrune 字符串值包含提供的特殊符号值 Field validate:"containsrune=☢"
excludes 字符串值不包含子字符串值 Field validate:"excludes=@"
excludesall 字符串值不包含任何子字符串值 Field validate:"excludesall=abc"
excludesrune 字符串值不包含提供的特殊符号值 Field validate:"containsrune=☢"
startswith 字符串以提供的字符串值开始 Field validate:"startswith=abc"
endswith 字符串以提供的字符串值结束 Field validate:"endswith=abc"
ip 字符串值是否包含有效的 IP 地址 Field validate:"ip"
ipv4 字符串值是否包含有效的 ipv4地址 Field validate:"ipv4"
datetime 字符串值是否包含有效的 日期 Field validate:"datetime"

四、标记使用注意

1、当搜索条件与特殊标记冲突时,如:逗号(,),或操作(|),中横线(-)等则需要使用 UTF-8十六进制表示形式

例:

type Test struct {
   Field1 string  `validate:"excludesall=|"`    // 错误
   Field2 string `validate:"excludesall=0x7C"` // 正确.
}

2、可通过validationErrors := errs.(validator.ValidationErrors)获取错误对象自定义返回响应错误 3、自定义校验结果翻译

// 初始化翻译器
func validateInit() {
	zh_ch := zh.New()
	uni := ut.New(zh_ch)               // 万能翻译器,保存所有的语言环境和翻译数据
	Trans, _ = uni.GetTranslator("zh") // 翻译器
	Validate = validator.New()
	_ = zh_translations.RegisterDefaultTranslations(Validate, Trans)
	// 添加额外翻译
	_ = Validate.RegisterTranslation("required_without", Trans, func(ut ut.Translator) error {
		return ut.Add("required_without", "{0} 为必填字段!", true)
	}, func(ut ut.Translator, fe validator.FieldError) string {
		t, _ := ut.T("required_without", fe.Field())
		return t
	})
}

五、使用示例

package main
import (
   "fmt"
   "github.com/go-playground/validator/v10"
)
// 实例化验证对象
var validate = validator.New()
func main() {
   // 结构体验证
   type Inner struct {
      String string `validate:"contains=111"`
   }
   inner := &Inner{String: "11@"}
   errs := validate.Struct(inner)
   if errs != nil {
      fmt.Println(errs.Error())
   }
   // 变量验证
   m := map[string]string{"": "", "val3": "val3"}
   errs = validate.Var(m, "required,dive,keys,required,endkeys,required")
   if errs != nil {
      fmt.Println(errs.Error())
   }
}

包下载:go get github.com/go-playground/validator/v10
demo示例:https://github.com/Jambo-Git/validator-demo

Centos上配置开机自启动的几种方式

CentOS开机自动启动脚本

前言

Linux作为服务器实在是太香了,唯一麻烦的就是服务器重启的时候,一些程序又得手动启动。其实可以通过添加开机自动启动脚本的方法来进行自动启动。

自启动方法

在/etc/rc.d/rc.local中添加启动脚本

chmod +x /etc/rc.d/rc.local

二、在 /etc/rc.d/rc.local 中添加要执行的指定命令

在 /etc/rc.d/rc.local 中添加要执行的指定命令,格式如下:

su - 用户 -c “执行命令”

示例如下:

su - root -c "/home/source/start-api.sh"

手动配置

1、在/etc/rc.d/rc.local中添加服务启动命令

/etc/rc.d/rc.local脚本会在Centos系统启动时被自动执行,所以可以把需要开机后执行的命令直接放在这里。

示例:配置开机启动apollo

vi /etc/rc.d/rc.local

想简单点可以像上面这样直接将服务的启动命令添加到/etc/rc.d/rc.local中。

也可以自己编写服务启动的脚本。由于重启时是以root用户重启,需要保证root用户有脚本执行权限。

1)、编写服务启动的脚本

vi /opt/script/autostart.sh

#!/bin/bash
/root/Downloads/docker-quick-start/docker-compose up -d

2)、赋予脚本可执行权限(/opt/script/autostart.sh是你的脚本路径)

chmod +x /opt/script/autostart.sh

3)、打开/etc/rc.d/rc.local文件,在末尾增加如下内容

/opt/script/autostart.sh

3)、在centos7中,/etc/rc.d/rc.local的权限被降低了,所以需要执行如下命令赋予其可执行权限

chmod +x /etc/rc.d/rc.local

通过chkconfig配置

在CentOS7之前,可以通过chkconfig来配置开机自启动服务。

chkconfig相关命令:

chkconfig –-add xxx //把服务添加到chkconfig列表
chkconfig --del xxx //把服务从chkconfig列表中删除
chkconfig xxx on //开启开机自动启动
chkconfig xxx off //关闭开机自动启动
chkconfig --list //查看所有chklist中服务
chkconfig --list xxx 查看指定服务

chkconfig运行级别level和启动顺序的概念:

chkconfig --list

这里的0到6其实指的就是服务的level。
–level<等级代号> 指定系统服务要在哪一个执行等级中开启或关毕。
等级0表示:表示关机
等级1表示:单用户模式
等级2表示:无网络连接的多用户命令行模式
等级3表示:有网络连接的多用户命令行模式
等级4表示:不可用
等级5表示:带图形界面的多用户模式
等级6表示:重新启动
比如如下命令:

//设定mysqld在等级3和5为开机运行服务
chkconfig --level 35 mysqld on 
//设置network服务开机自启动,会把2~5的等级都设置为on
chkconfig network on

表示开机启动配置成功。
服务的启动顺序又指的什么呢?
服务的启动顺序是指在服务器启动后服务启动脚本执行的顺序。
以系统默认服务network说明:

cat /etc/init.d/network

其中 # chkconfig: 2345 10 90用来指定服务在各个level下的启动顺序。
该配置的含义是network服务在2、3、4、5的level下的启动顺序是10,在1和6的level等级下的启动顺序是90。
chkconfig配置的服务启动顺序最后都会在/etc/rc.d/目录下体现出来:

cd /etc/rc.d/

文件中脚本命名规则,首字母K表示关闭脚本,首字母S表示启用脚本,数字表示启动的顺序.
chkconfig配置实例
通常kibana的官方配置是没有介绍如何配置开机自启动的。这里我配置kibana开机自启动来说明。
1、在/etc/init.d目录下,新建脚本kibana

cd /etc/init.d
vi kibana

脚本内容如下:

#!/bin/bash
# chkconfig: 2345 98 02
# description:  kibana
KIBANA_HOME=/usr/local/kibana-6.2.4-linux-x86_64
case $1 in
 start)
         $KIBANA_HOME/bin/kibana &
         echo "kibana start"
         ;;
 stop)
    kibana_pid_str=`netstat -tlnp |grep 5601 | awk '{print $7}'`
    kibana_pid=`echo ${kibana_pid_str%%/*}`
    kill -9 $kibana_pid
    echo "kibana stopped"
    ;;
 restart)
    kibana_pid_str=`netstat -tlnp |grep 5601 | awk '{print $7}'`
    kibana_pid=${kibana_pid_str%%/*}
    kibana_pid=`echo ${kibana_pid_str%%/*}`
    kill -9 $kibana_pid
    echo "kibana stopped"
    $KIBANA_HOME/bin/kibana &
    echo "kibana start"
    ;;
 status)
    kibana_pid_str=`netstat -tlnp |grep 5601 | awk '{print $7}'`
    if test -z $kibana_pid_str; then
       echo "kibana is stopped"
    else
       pid=`echo ${kibana_pid_str%%/*}`
       echo "kibana is started,pid:"${pid}
    fi
    ;;
*)
    echo "start|stop|restart|status"
    ;;
esac

注意⚠️:
每个被chkconfig管理的服务需要在对应的init.d下的脚本加上两行或者更多行的注释。
第一行告诉chkconfig缺省启动的运行级以及启动和停止的优先级。如果某服务缺省不在任何运行级启动,那么使用 – 代替运行级。
第二行对服务进行描述,可以用\ 跨行注释。

#!/bin/bash
#chkconfig:2345 98 02
#description:kibana

解释说明:
配置kibana服务在2、3、4、5的level等级下脚本执行顺序是98,
1、6的level等级下脚本执行顺序是01。
2、增加脚本的可执行权限

chmod +x kibana

3、查看chkconfig list

chkconfig --list

4、把服务添加到chkconfig列表

chkconfig --add kibana

5、设置kibana服务自启动

chkconfig kibana on //开启开机自动启动

6、查看kibana服务自启动状态

chkconfig --list kibana

7、服务的启动、停止、重启和状态查看

//查看服务状态
service kibana status
//服务启动
service kibana start
//服务停止
service kibana stop
//服务重启
service kibana restart

Golang操作MongoDB:mongo-driver

这篇文章主要介绍了使用GO操作MongoDB,包括安装MongoDB驱动程序连接mongodb的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

1.安装 MongoDB Go 驱动程序

MongoDB Go Driver 由几个包组成。如果您只是使用 go get,则可以使用以下命令安装驱动程序:

go get github.com/mongodb/mongo-go-driver

这个输出可能看起来像一个警告,说明类似于 package github.com/mongodb/mongo-go-driver: no Go files in (…)。这是预期的输出。

如果您使用 govendor 包管理器,则需要使用以下命令安装主 mongo 包以及 bson 和 mongo/options 包:

govendor fetch github.com/mongodb/mongo-go-driver/mongo

govendor fetch go.mongodb.org/mongo-driver/bson

govendor fetch go.mongodb.org/mongo-driver/mongo/options

2.设置连接

导入 MongoDB Go 驱动程序后,我们可以使用 Client.Connect(context) 连接到 MongoDB 部署。我们需要设置一个新客户端,我们需要在设置客户端时传递 mongo 数据库的 URI。然后我们只需要使用上下文调用 client.Connect(context),这将建立我们的连接。

以下代码为我们建立了一个连接:

//Set up a context required by mongo.Connect
ctx, cancel := context.WithTimeout(context.Background(), 10\*time.Second)

//To close the connection at the end
defer cancel()

//We need to set up a client first
//It takes the URI of your database
client, error := mongo.NewClient(options.Client().ApplyURI("your\_database\_uri"))

if error != nil {
 log.Fatal(err)
}

//Call the connect function of client
error = client.Connect(ctx)

//Checking the connection
error = client.Ping(context.TODO(), nil)
fmt.Println("Database connected")

3.在 Go 中使用 BSON 对象

MongoDB 中的 JSON 文档存储在称为 BSON(二进制编码 JSON)的二进制表示中。与将 JSON 数据存储为简单字符串和数字的其他数据库不同,BSON 编码扩展了 JSON 表示以包括其他类型,例如 int、long、date、floating point 和 decimal128。这使得应用程序更容易可靠地处理、排序和比较数据。 Go Driver 有两个表示 BSON 数据的类型:D 类型和 Raw 类型。

D 系列类型用于使用本机 Go 类型简洁地构建 BSON 对象。这对于构造传递给 MongoDB 的命令特别有用。 D 系列包括四种类型:

  • D:BSON 文档。这种类型应该在顺序很重要的情况下使用,例如 MongoDB 命令。
  • M:无序映射。它与 D 相同,只是它不保持顺序。
  • A:一个 BSON 数组。
  • E:D 中的单个元素。

这是一个使用 D 类型构建的过滤器文档的示例,可用于查找名称字段与 Alice 或 Bob 匹配的文档:

bson.D{{
 "name", 
 bson.D{{
 "$in", 
 bson.A{"Alice", "Bob"}
 }}
}}

4. CRUD 操作

对于 CRUD 和其他操作,我们需要使用集合对象,我们可以通过引用数据库中各自的集合来创建它,例如:

BooksCollection := client.Database("test").Collection("books")

插入
对于创建,我们可以将 collection.InsertOne() 用于单个条目,也可以使用 collection.InsertMany() 来接收对象切片。

/\*\*
\* Create - Adding a new book
\* res -\> the insert command returns the inserted id of the oject
\*/

res, err := BooksCollection.InsertOne(ctx, bson.M{"name": "The Go Language", "genre": "Coding", "authorId": "4"})

if err != nil {
log.Fatal(err)
}

在 collection.InsertOne() 中,我们可以通过 bson.M{} 传递一个字符串对象,或者我们可以创建一个我们各自类型结构的对象并传递该对象。

阅读
为了查找文档,我们需要一个过滤文档以及一个指向可以将结果解码成的值的指针。要查找单个文档,请使用 collection.FindOne()。此方法返回一个可以解码为值的结果。过滤器对象指定我们要查找的内容。

filter := bson.D{{"name", "Book 1"}}

// create a value into which the result can be decoded
var result bookType

err = collection.FindOne(context.TODO(), filter).Decode(&result)
if err != nil {
 log.Fatal(err)
}

fmt.Printf("Found a single Book: %+v\n", result)

要查找多个文档,请使用 collection.Find()。此方法返回一个光标。游标提供了一个文档流,我们可以通过它一次迭代和解码一个。一旦游标用尽,我们应该关闭游标。

cur, error := BooksCollection.Find(ctx, bson.D{{}})

var allbooks []\*bookType

//Loops over the cursor stream and appends to result array
for cur.Next(context.TODO()) {
var booksResultHolder bookType

err := cur.Decode(&bookResultHolder)

if err != nil {
log.Fatal(err)
}

allbooks = append(allbooks, &booksResultHolder)
}

//dont forget to close the cursor
defer cur.Close(context.TODO())

// Loop over the result array and perform whatever required
for \_, element := range allbooks {
book := \*element
fmt.Println(book)
}

更新
collection.UpdateOne() 方法允许您更新单个文档。它需要一个过滤文档来匹配数据库中的文档,并需要一个更新文档来描述更新操作。这些可以按照我们在阅读时制作过滤器对象的方式构建。

/\*\*
\* Update
\* Collection has functions like UpdateOne and UpdateMany
\* Returns the Matched and Modified Count
\*/

filter := bson.D{{"name", "Book 1"}}

// Need to specify the mongodb output operator too
newName := bson.D{
{"$set", bson.D{
{"name", "Updated Name of Book 1"},
}},
}

res, err := BooksCollection.UpdateOne(ctx, filter, newName)

if err != nil {
log.Fatal(err)
}

updatedObject := \*res

fmt.Printf("The matched count is : %d, the modified count is : %d", updatedObject.MatchedCount, updatedObject.ModifiedCount)

删除
最后,我们可以使用 collection.DeleteOne() 或 collection.DeleteMany() 删除文档。在这里,我们可以传递 nil 作为过滤器参数,它将匹配集合中的所有文档或任何其他特定参数。我们还可以使用collection.Drop()删除整个集合。

filter = bson.D{{"name", "Updated Name of Book 2"}}

deleteResult, error := BooksCollection.DeleteOne(ctx, filter)

后续步骤
本教程的源代码可以在这里找到。

MongoDB Go 驱动程序的文档可在GoDoc上找到。您可能对有关使用聚合或交易的文档特别感兴趣。

希望本教程对您来说更简单,祝大家编码愉快!

mongodb – 内存占用过高,wiredTigerCacheSizeGB限制

问题

在使用 MongoDB 过程中,会遇到 内存占用随着数据操作而线性增加 的情况;
如果数据持续的大量写入的话,会大量占用服务器内存,出现 OOM 问题,在服务器内存保护机制作用下,MongoDB 会被 kill 掉。

内存增加的原因

mongo为了优化他的读写效率,将内存当做缓存,所以你读写次数越多,缓存就越大。默认值:
从3.4开始,WiredTiger内部缓存默认使用较大的一个, 我用的是4.1
50%(RAM – 1 GB),或256 MB。
例如,我是8G内存,那么最大缓存0.5*(8-1)=3.5G,看到了么。。。mongo默认3.5G都是他的缓存。

cacheSizeGB的介绍

storage.wiredTiger. engineConfig.cacheSizeGB

wiredtiger将使用所有数据的最大缓存大小,wiredTiger缓存工作集(working set)数据的内存大小,单位:GB,

此值决定了wiredTiger与mmapv1的内存模型不同,它可以限制mongod对内存的使用量,而mmapv1则不能(依赖于系统级的mmap)。

默认情况下,cacheSizeGB的值为假定当前节点只部署一个mongod实例,在MongoDB 3,默认情况下,wiredtiger缓存,使用1 GB或安装的物理内存的一半,以较大者为准。

如果当前节点部署了多个mongod进程,那么需要合理配置此值。

如果mongod部署在虚拟容器中(比如,lxc,cgroups,Docker)等,它将不能使用整个系统的物理内存,则需要适当调整此值。默认值为物理内存的一半。

解决

在配置中限制mongo的缓存大小, 引擎需要更换为wiredTiger 默认的mmapv1依赖于mmap不能指定
官方也声称wiredTiger更加优秀
修改(增加)cacheSizeGB配置。

配置如下:

# Where and how to store data.
  engine: wiredTiger
#  mmapv1:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1

使用Go编译为可执行文件(windows/linux)

案例场景:创建一个两层目录,并在该目录下创建一个文件,将“Hello World”字符写入该文件,并读取出来。

目标:(1)测试案例是否能执行成功;(2)编译代码成windows与linux两种环境下的可执行文件。

测试代码文件名为main.go,内容如下:

package main
 
import (
	"fmt"
	"io/ioutil"
	"os"
)
 
func main() {
	// 文件夹名
	_dir := "data/test"
	exist, err := pathExists(_dir)
	if err != nil {
		fmt.Printf("get dir error![%v]\n", err)
		return
	}
 
	if exist {
		fmt.Printf("has dir![%v]\n", _dir)
	} else {
		fmt.Printf("no dir![%v]\n", _dir)
		// 创建文件夹
		//err := os.Mkdir(_dir, os.ModePerm)
		err := os.MkdirAll(_dir, 0666)
		if err != nil {
			fmt.Printf("mkdir failed![%v]\n", err)
		} else {
			fmt.Printf("mkdir success!\n")
			fileName := _dir + "/test.txt"
			// 创建文件
			os.Create(fileName)
			// 打开文件
			file, _ := os.OpenFile(fileName, os.O_WRONLY|os.O_APPEND, 0666)
			// 当执行完,关闭文件
			defer file.Close()
			// 写内容到文件中
			file.WriteString("Hello World!")
			//读取文件
			data, _ := ioutil.ReadFile(fileName)
			// 打印内容
			fmt.Println(string(data))
		}
	}
}
 
func pathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

经过调试,上述代码可正常执行。测试通过。

编译成windows环境exe可执行文件过程,打开文件所在目录,在资源路径框中输入cmd,打开cmd命令框,通过“go env”查看当期环境变量,以windows10环境为例,默认为windows环境。

// 配置环境变量
SET CGO_ENABLED=1
SET GOOS=windows
SET GOARCH=amd64
// 编译命令
go build main.go

编译出来后就是一个可执行文件main.exe,可用鼠标双击直接执行,传到其他电脑上操作,依然可执行,不依赖第三方包(不像Java会依赖JDK)。

执行后,在main.exe所在目录下,生成一个data/test/test.txt,并且打开test.txt文件可看到Hello World。

编译成Linux环境可执行文件,此处除编译环境参数外,其他步骤与上面类似,编译参数如下

// 配置参数
SET CGO_ENABLED=0 
SET GOOS=linux 
SET GOARCH=amd64 
// 编译命令
go build main.go

编译输出的可执行文件名为main,上传至centos7.x系统,使用 “chmod +x main”添加可执行权限,执行 ” ./main “,输出结果与上述windows结果一样。

备注:上述编译环境所在的操作系统均为Windows10,即在windows10上开发代码,编译输出windows与linux两种环境的可执行文件。