日常工作软件安装总结

日常工作软件安装总结

系统服务安装集成

Skywalking

SpringBoot集成Skywalking服务

地址:http://192.168.1.52:8686/general

nohup java -javaagent:/mnt/skywalking-agent/skywalking-agent/skywalking-agent.jar -DSW_AGENT_NAME=dev::rms-risk-service agent.service_name=rms-risk-service -Dskywalking.collector.backend_service=192.168.1.52:11800 -jar rms-risk-service.jar &

nohup java -javaagent:/mnt/skywalking-agent/skywalking-agent-system/skywalking-agent.jar -DSW_AGENT_NAME=dev::rms-system-service -Dskywalking.collector.backend_service=192.168.1.52:11800 -jar rms-system-service.jar &

nohup java -javaagent:/mnt/skywalking-agent/skywalking-agent-basic/skywalking-agent.jar -DSW_AGENT_NAME=dev::rms-basic-service -Dskywalking.collector.backend_service=192.168.1.52:11800 -jar rms-basic-service.jar &

skywalking9.1结合logback配置日志收集

首先保证自己已经有了SkyWalking APM服务(如果没有安装skywalking可参考https://blog.csdn.net/m0_49405757/article/details/134015206),接着去官网下载Java Agent。这里下载的是8.15.0版本的tar包。

在这里插入图片描述

直接将tar包解压出来,这边是将解压出来的文件夹直接放到了项目中(可以放到任意位置)

在这里插入图片描述

接着引入maven依赖

   <properties><apm-logback.version>9.0.0</apm-logback.version></properties><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>${apm-logback.version}</version></dependency>

配置logback并在日志中打印traceId,在日志输出格式中添加%tid即可。可参考官网

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 日志输出格式 --><property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] %green(%-5level) [%thread] %yellow([%tid]) %cyan(%logger{50}) : %msg%n" /><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!-- 默认日志打印的格式 --><!--<encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>utf-8</charset></encoder>--><!-- 配置了skywalking的traceId的日志打印的格式 --><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><Pattern>${FILE_LOG_PATTERN}</Pattern></layout></encoder></appender><!-- 异步输出 控制台 --><appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>256</queueSize><appender-ref ref="STDOUT"/></appender><root level="info"><appender-ref ref="ASYNC_STDOUT"/></root>
</configuration>

在idea中配置服务启动时需要配置的jvm参数

-javaagent:skywalking-agent.jar的绝对路径
-Dskywalking.agent.service_name=你的服务名
-Dskywalking.agent.instance_name=你的实例名(可以和服务名保持一致)
-Dskywalking.collector.backend_service=ip:11800(如果skywlking服务不在本地,则需要配置上)

下面是我的参数配置

-javaagent:E:\ideaProject\mj-cloud\mj-registry\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=mj-permission
-Dskywalking.agent.instance_name=permission

接着启动服务(skywalking的服务也要启动),可以在控制台中看到tid已经打印出来了,但是由于启动时并没有调用其他服务,所以tid为N/A

在这里插入图片描述

启动之后调用了一个测试接口,可以看到tid已经打印出来了

在这里插入图片描述

skywalking还提供打印上下文的功能,只需将%tid替换为%sw_ctx,则日志会输出[$serviceName,$instanceName,$traceId,$traceSegmentId,$spanId]格式。

在这里插入图片描述

最后配置日志收集,需要在logback的配置文件中再添加一个appender

<!-- 使用gRpc将日志发送到skywalking服务端 --><appender name="GRPC_LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><Pattern>${FILE_LOG_PATTERN}</Pattern></layout></encoder></appender><root level="info"><appender-ref ref="ASYNC_STDOUT"/><appender-ref ref="GRPC_LOG"/></root>

并且将下面的配置添加到我们下载的agent的config文件夹下的agent.config末尾

# 指定要向其报告日志数据的GRPC服务器主机
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:skywalking服务所在机器的ip}
# 指定要向其报告日志数据的GRPC服务器端口
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
# 指定GRPC客户端要报告的日志数据的最大大小
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
# 客户端向上游发送数据时将超时多长时间,单位是秒
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

在这里插入图片描述

最后重启我们的服务,再次进行测试。打开skywalking的UI界面查看,选择我们的服务,点击log页签,可以看到测试的日志已经收集上了

在这里插入图片描述

点击日志可以看到追踪id和我们控制台打印的一样

在这里插入图片描述

在这里插入图片描述

至此,skywalking日志收集也已经完成。如果遇到问题一定要去查看日志,在我们安装的skywalking的logs文件夹下,主要看skywalking-oap-server.log

ELK

Sonarqube

Nacos

Docker

docker降级版本:

yum downgrade --setopt=obsoletes=0 -y docker-ce-19.03.13-3.el7 docker-ce-cli-19.03.13-3.el7 containerd.io

Centos7 安装docker

# centos7 安装docker 
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2#安装docker
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun#启动
service docker start# 设置开机启动
systemctl enable docker
Docker本地文件复制到容器
 docker cp /mnt/prometheus.yml 082195e34a9d:/etc/prometheus/prometheus.yml
Docker复制容器文件到本地
docker cp 082195e34a9d:/etc/prometheus/prometheus.yml /mnt

构建、上传镜像到Harbor

1、构建镜像
docker build -t docker-risk .
2、运行镜像
docker run --name docker-risk  -d -p 6080:6080  docker-risk
3、打标签
docker tag docker-risk01 192.168.1.107:80/rms/docker-risk01:latest
4、登录harbor
docker login 192.168.1.107:80
5、推送镜像到Harbor
docker push 192.168.1.107:80/rms/docker-risk01:latest
6、拉取镜像到本地
docker pull 192.168.1.107:80/rms/docker-risk01:latest

docker pull 192.168.1.107/rms/docker-system-service@sha256:4ddc493cd8cdc957e8228f8738e25f1ad3e4ebd076f906cdfa58c1fce9e18fb0

docker配置Harbor
{"exec-opts": ["native.cgroupdriver=systemd"],"storage-driver": "overlay2","log-driver": "json-file","log-opts": {"max-size": "100m"},"registry-mirrors": ["https://b9307g5p.mirror.aliyuncs.com"],"insecure-registries": ["192.168.1.107:80"]}

服务器位置:

/etc/docker/daemon.json
修改docker service

位置:

vim /usr/lib/systemd/system/docker.service
重新加载守护线程
systemctl daemon-reload

Docker安装部署Elasticsearch、kibana

一、安装Elasticsearch
1.1.创建网络
因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:

docker network create es-net

1.2.拉取
docker pull elasticsearch:7.12.1
1
1.3.运行
运行docker命令,部署单点es:

docker run -d \

--name es \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
--network es-net \
-p 9200:9200 \

elasticsearch:7.12.1

命令解释:

-e “cluster.name=es-docker-cluster”:设置集群名称
-e “http.host=0.0.0.0”:监听的地址,可以外网访问
-e “ES_JAVA_OPTS=-Xms512m -Xmx512m”:内存大小
-e “discovery.type=single-node”:非集群模式
-v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
-v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录
-v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
–privileged:授予逻辑卷访问权
–network es-net :加入一个名为es-net的网络中
-p 9200:9200:端口映射配置
在浏览器中输入:http://IP地址:9200 即可看到elasticsearch的响应结果:

二、部署kibana
2.1.部署
拉取镜像命令

docker pull kibana:7.12.1

运行docker命令,部署kibana

docker run -d
–name kibana
-e ELASTICSEARCH_HOSTS=http://es:9200
–network=es-net
-p 5601:5601
kibana:7.12.1

–network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中
-e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
-p 5601:5601:端口映射配置
此时,在浏览器输入地址访问:http://IP地址:5601,即可看到结果

Docker elasticserch集群搭建

useradd esUser
(base) [username@opencloudos ~]$ groups
username docker
或者
(base) [username@opencloudos ~]$ groups username
username : username docker

一般回复的是当前用户所在的分组,看看当前用户username在不在docker组中。如果不在,可以使用以下命令将用户添加到docker组。(注意将username替换成真实的用户名),此处需要使用root或者sudo权限

usermod -aG docker esUser

#停止容器

docker stop d2c410563678

#删除容器

docker rm d2c410563678

查看镜像内容

docker logs <容器ID或名称>

报错:

this Docker version is not on the list of validated versions: 24.0.7. Latest validated version: 20.1

报错信息可以看出跟docker的版本有关系,意思是:此 Docker 版本不在已验证版本列表中:24.0.7。 最新验证版本:20.10

降低docker版本到20.10
1、查看当前仓库支持的docker版本

yum list docker-ce --showduplicates | sort -r

2、降低docker版本到3:20.10.9-3.el8

语法: yum downgrade --setopt=obsoletes=0 -y docker-ce-v e r s i o n d o c k e r − c e − s e l i n u x − {version} docker-ce-selinux-versiondocker−ce−selinux−{version}

降低docker版本到3:20.10.9-3.el8

yum downgrade --setopt=obsoletes=0 -y docker-ce-3:20.10.9-3.el8 docker-ce-cli-3:20.10.9-3.el8 containerd.io

3、查看降级后版本

systemctl start docker

docker version

Docker Elasticsearch集群部署

查看集群详情

192.168.1.113:9200/_cat/nodes?pretty

环境

(1)Centos7
(2)Docker 23.0.1
(3)Elasticsearch 7.16.3

服务器

名称ip地址内存
节点一192.168.1.11316G
节点二192.168.1.11416G
节点三192.168.1.11516G

部署

在三个服务器节点上执行如下操作:

准备映射目录
切换到/home目录中,创建elasticsearch目录,切换到elasticsearch目录中。

cd /home/
mkdir elasticsearch
cd elasticsearch

临时启动elasticsearch

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.16.3

复制容器中配置目录到磁盘目录

cd /home/elasticsearch
docker cp elasticsearch:/usr/share/elasticsearch/config .
docker cp elasticsearch:/usr/share/elasticsearch/data .
docker cp elasticsearch:/usr/share/elasticsearch/plugins .

授予elasticsearch目录及子目录改文件及子文件所有权限

chmod -R 777 elasticsearch

移除临时启动elasticsearch容器

docker stop elasticsearch
docker rm elasticsearch

3.1 节点一

修改/home/elasticsearch/config/elasticsearch.yml配置文件

# 集群名称 所有节点名称一致
cluster.name: es-clusters
# 当前该节点的名称,每个节点不能重复es-node-1,es-node-2,es-node-3
node.name: es-node-1
# 当前该节点是不是有资格竞选主节点
node.master: true
# 当前该节点是否存储数据
node.data: true
# 设置为公开访问
network.host: 0.0.0.0
# 设置其它节点和该节点交互的本机器的ip地址,三台各自为
network.publish_host: 192.16.109.113
# 设置映射端口
http.port: 9200
# 内部节点之间沟通端口
transport.tcp.port: 9300# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"# 配置集群的主机地址
discovery.seed_hosts: ["192.16.109.113","192.16.109.114","192.16.109.115"]
# 初始主节点,使用一组初始的符合主条件的节点引导集群
cluster.initial_master_nodes: ["es-node-1","es-node-2","es-node-3"]
# 节点等待响应的时间,默认值是30秒,增加这个值,从一定程度上会减少误判导致脑裂
discovery.zen.ping_timeout: 30s
# 配置集群最少主节点数目,通常为 (可成为主节点的主机数目 / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 禁用交换内存,提升效率
bootstrap.memory_lock: false

正式运行elasticsearch

docker run --name=elasticsearch-node-1 -p 9200:9200 -p 9300:9300 \
-e ES_JAVA_OPTS="-Xms4g -Xmx4g" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
--restart=always \
-d elasticsearch:7.16.3

节点二

修改/home/elasticsearch/config/elasticsearch.yml配置文件

# 集群名称 所有节点名称一致
cluster.name: es-clusters
# 当前该节点的名称,每个节点不能重复es-node-1,es-node-2,es-node-3
node.name: es-node-2
# 当前该节点是不是有资格竞选主节点
node.master: true
# 当前该节点是否存储数据
node.data: true
# 设置为公开访问
network.host: 0.0.0.0
# 设置其它节点和该节点交互的本机器的ip地址,三台各自为
network.publish_host: 192.16.109.114
# 设置映射端口
http.port: 9200
# 内部节点之间沟通端口
transport.tcp.port: 9300# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"# 配置集群的主机地址
discovery.seed_hosts: ["192.16.109.113","192.16.109.114","192.16.109.115"]
# 初始主节点,使用一组初始的符合主条件的节点引导集群
cluster.initial_master_nodes: ["es-node-1","es-node-2","es-node-3"]
# 节点等待响应的时间,默认值是30秒,增加这个值,从一定程度上会减少误判导致脑裂
discovery.zen.ping_timeout: 30s
# 配置集群最少主节点数目,通常为 (可成为主节点的主机数目 / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 禁用交换内存,提升效率
bootstrap.memory_lock: false

正式运行elasticsearch

docker run --name=elasticsearch-node-2 -p 9200:9200 -p 9300:9300 \
-e ES_JAVA_OPTS="-Xms4g -Xmx4g" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
--restart=always \
-d elasticsearch:7.16.3

节点三

修改/home/elasticsearch/config/elasticsearch.yml配置文件

# 集群名称 所有节点名称一致
cluster.name: es-clusters
# 当前该节点的名称,每个节点不能重复es-node-1,es-node-2,es-node-3
node.name: es-node-3
# 当前该节点是不是有资格竞选主节点
node.master: true
# 当前该节点是否存储数据
node.data: true
# 设置为公开访问
network.host: 0.0.0.0
# 设置其它节点和该节点交互的本机器的ip地址,三台各自为
network.publish_host: 192.16.109.115
# 设置映射端口
http.port: 9200
# 内部节点之间沟通端口
transport.tcp.port: 9300# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"# 配置集群的主机地址
discovery.seed_hosts: ["192.16.109.113","192.16.109.114","192.16.109.115"]
# 初始主节点,使用一组初始的符合主条件的节点引导集群
cluster.initial_master_nodes: ["es-node-1","es-node-2","es-node-3"]
# 节点等待响应的时间,默认值是30秒,增加这个值,从一定程度上会减少误判导致脑裂
discovery.zen.ping_timeout: 30s
# 配置集群最少主节点数目,通常为 (可成为主节点的主机数目 / 2) + 1
discovery.zen.minimum_master_nodes: 2
# 禁用交换内存,提升效率
bootstrap.memory_lock: false

正式运行elasticsearch

docker run --name=elasticsearch-node-3 -p 9200:9200 -p 9300:9300 \
-e ES_JAVA_OPTS="-Xms4g -Xmx4g" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
--restart=always \
-d elasticsearch:7.16.3

查看集群是否成功

在浏览器上输入http://任一节点ip:9200/_cat/nodes?pretty查看集群信息,出现如下信息就代表集群搭建成功了。

192.16.109.113 20 99 1 0.03 0.04 0.06 cdfhilmrstw * es-node-3
192.16.109.114 12 99 3 0.03 0.05 0.06 cdfhilmrstw - es-node-1
192.16.109.114 56 89 2 0.19 0.12 0.13 cdfhilmrstw - es-node-2

注意事项

运行elasticsearch启动参数

注意:我们启动参数设置的-e ES_JAVA_OPTS="-Xms4g -Xmx4g",根据服务器内存实际情况调整。
● Xms 为jvm启动是分配的最大内存
● Xmx 为jvm运行过程分配的最大内存

修改虚拟内存最大映射数
系统虚拟内存默认最大映射数为65530,无法满足ES系统要求,需要调整为262144以上。
sudo vi /etc/sysctl.conf

#添加参数
vm.max_map_count = 655360

重新加载/etc/sysctl.conf配置

sysctl -p

各节点无法组成集群,各自都是master的解决办法

(1)关闭所有节点,或者直接删除容器
(2)在三个节点上清空/home/elasticsearch/data节点数据

cd /home/elasticsearch/data
rm -rf *

重新启动所有节点

Jenkins

1、下载Jenkins.war包,上传到Linux服务器

2、执行命令

注意:

必须在jenkins.war目录下执行

nohup java -jar jenkins.war --ajp13Port=-1 --httpPort=8081 &

jenkins启动默认密码:

*************************************************************
*************************************************************
*************************************************************Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:d8657ad599424ba1b81e336b489f3602This may also be found at: /root/.jenkins/secrets/initialAdminPassword*************************************************************
*************************************************************
*************************************************************

3、等待Jenkins安装依赖,可能会报错

4、配置jdk路径、下载maven配置maven路径、下载git,配置git路径

5、

-Dmaven.test.skip=true

Prometheus

1、使用docker安装

2、镜像地址配置路径:

/etc/prometheus/prometheus.yml
# my global config
global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:# - alertmanager:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["localhost:9090"]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

docker进入容器报:Error response from daemon: Container ******* is not running

根据docker所报的错,问题出现的有以下:

1、由于 docker容器未启动。

2、网络问题,网络配置修改了,但未重启网络。

3、配置文件问题,文件修改过程中出错了。

一、docker容器未启动解决方法:启动容器

操作步骤:

1.使用命令查看docker容器id:docker ps -a;

img

2.使用命令:docker start 容器id,启动docker容器。

img

3.然后即可使用命令:docker exec -it 容器id /bin/bash进入docker容器。

img

二、网络配置更改了,解决方法:重启网络

使用命令:source /etc/profile

三、配置文件问题,解决方法:修改配置文件

示例:mysql中的配置文件更改中出错了,操作步骤如下:

1、从容器中将配置文件复制到本地

docker cp 容器id:/etc/mysql/my.cnf /opt

2、在本地修改配置文件,并保存

使用命令:vi /opt/my.cnf

3、将更改后的配置文件复制到docker容器中

docker cp /opt/my.cnf 容器id:/etc/mysql

4、重启容器

docker restart 容器id

5、查看docker容器中启动的进程

docker ps -a

即问题解决。

附注:

1.如果需要设置docker中MySQL自启,使用命令:docker update mysql --restart=always 容器id;

2.docker设置开机自启,使用命令:system enable docker;

java.lang.ClassNotFoundException: io.prometheus.client.Gauge

在Java开发中,我们经常会遇到各种异常,其中一个常见的异常是java.lang.ClassNotFoundException。这个异常通常是由于类路径问题引起的,即JVM无法找到所需的类。在本文中,我们将讨论一个特定的ClassNotFoundException:io.prometheus.client.Gauge。
io.prometheus.client.Gauge是一个Prometheus客户端库中的类,用于创建和管理Gauge指标。Prometheus是一个开源的监控系统,它可以收集和存储各种指标,并提供查询和可视化功能。Gauge是一种指标类型,它表示一个单一的数值,可以随时间变化。例如,我们可以使用Gauge来表示服务器的CPU使用率或内存使用量。
在使用Prometheus客户端库时,我们需要将其添加到我们的项目中。通常,我们可以使用Maven或Gradle等构建工具来管理依赖项。以下是一个使用Maven的示例pom.xml文件:

<dependencies><dependency><groupId>io.prometheus</groupId><artifactId>simpleclient</artifactId><version>0.11.0</version></dependency><dependency><groupId>io.prometheus</groupId><artifactId>simpleclient_pushgateway</artifactId><version>0.11.0</version></dependency><dependency><groupId>io.prometheus</groupId><artifactId>simpleclient_servlet</artifactId><version>0.11.0</version></dependency>
</dependencies>

prometheus.yml样例

# my global config
global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:- 192.168.1.56:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"- "/etc/prometheus/rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["192.168.1.56:9090"]
#  - job_name: 'mysql'
#    static_configs:
#      - targets: ['192.168.1.101:3306']- job_name: 'nacos'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.metrics_path: '/nacos/actuator/prometheus'static_configs:- targets: ['192.168.1.111:8848']# 新添加的采集目标admin服务- job_name: "rms-admin-service"metrics_path: '/actuator/prometheus'static_configs:- targets: ["192.168.1.51:6091"]# 新添加的采集目标risk服务- job_name: "rms-risk-service"metrics_path: '/actuator/prometheus'static_configs:- targets: ["192.168.1.51:6080"]- job_name: "rms-system-service"metrics_path: '/actuator/prometheus'static_configs:- targets: ["192.168.1.51:6060"]- job_name: "rms-basic-service"metrics_path: '/actuator/prometheus'static_configs:- targets: ["192.168.1.51:6070"]- job_name: "node-exporter"
#    metrics_path: '/actuator/prometheus'static_configs:- targets: ["192.168.1.56:9100"]#  # 新添加的采集目标elasticsearch服务
#  - job_name: "elasticsearch"
#    static_configs:
#      - targets: ["192.168.1.55:9200"]
#      
#  # 新添加的采集目标web前端服务
#  - job_name: "rms-web"
#    static_configs:
#      - targets: ["192.168.1.2:3110"]
#
#  # 新添加的采集目标web前端服务
#  - job_name: "skywalking"
#    static_configs:
#      - targets: ["192.168.1.52:8686"]

alertmanager.yml样例

global:resolve_timeout: 5mroute: # 告警路由配置,定义如何处理和发送告警receiver: webhookgroup_wait: 30sgroup_interval: 1mrepeat_interval: 4hgroup_by: [alertname]routes:- receiver: webhookgroup_wait: 10sreceivers: # 告警接收者配置,定义如何处理和发送告警
- name: webhookwebhook_configs:- url: http://192.168.1.56:8060/dingtalk/webhook1/send  # 告警 Webhook URLsend_resolved: true # 是否发送已解决的告警。如果设置为 true,则在告警解决时发送通知

Grafana

Dashboards实例值:10467

docker run -d \--name mysql_exporter \--restart always \-p 9104:9104 \-e DATA_SOURCE_NAME="user:password@(192.168.1.56:3306)/" \prom/mysqld-exporter
version: '3.2'networks:mysql-exporter-test:driver: bridgeservices:mysql:image: mysqlcontainer_name: mysql-testvolumes:- ./docker-volumes/mysql/db_data:/var/lib/mysql- ./docker-volumes/mysql/config/init:/docker-entrypoint-initdb.d/command: ['--character-set-server=utf8mb4','--collation-server=utf8mb4_unicode_ci','--default-time-zone=+8:00']environment:MYSQL_ROOT_PASSWORD: rootMYSQL_USER: rootMYSQL_PASSWORD: Rlyy#234ports:- 3306:3306networks:- mysql-exporter-testmysqld-exporter:image: prom/mysqld-exportercontainer_name: exporter-testports:- 9104:9104environment:- DATA_SOURCE_NAME=exporter:Prometheus@(mysql-test:3306)/depends_on:- mysqlnetworks:- mysql-exporter-testprometheus:image: prom/prometheus:latestcontainer_name: prometheusvolumes:- ./docker-volumes/prometheus/config/prometheus.yml:/etc/prometheus/prometheus.yml- ./docker-volumes/prometheus/data/prometheus_data:/prometheusenvironment:- TZ=Asia/Shanghaiports:- 9090:9090networks:- mysql-exporter-test
docker run -d -p 9104:9104 \-e DATA_SOURCE_NAME="root:Rlyy#234@(192.168.1.56:3306)/rms_risk" \--name mysql-exporter prom/mysqld-exporter

Grafana常用监控模板大全

Grafana常用监控模板大全 - 眈眈逐逐 - 博客园 (cnblogs.com)

1.服务器系统性能监控:8919
2.微服务性能监控:4701
3.docker环境性能监控:893
4.nacos性能监控:13221
5.mysql性能监控:9362
6.elasticsearch:266
7.SpringBoot:6756,springcloud:12856
8、redis:763

Alertmanager

alertmanager配置短信告警

alertmanager配置日志目录

alertmanager配置短信接口

alertmanager配置文件监听

alertmanager配置监控

alertmanager配置动态加载

alertmanager配置webhook

alertmanager配置钉钉告警

alertmanager配置basicauth

alertmanager配置多个webhook

Docker部署Prometheus+dingtalk+alertmanager告警

准备工作

拉取镜像

docker pull prom/node-exporter
docker pull grafana/grafana 
docker pull prom/prometheus 
docker pull prom/alertmanager 
docker pull timonwong/prometheus-webhook-dingtalk

一、安装node-exporter

docker run -d -p 9100:9100 --name node-exporter -v /home/node-exporter/proc:/host/proc:ro -v /home/node-exporter/sys:/host/sys:ro -v /home/node-exporter/:/rootfs:ro prom/node-exporter

http://192.168.0.201:9100/

img

二、安装Prometheus

1、配置prometheus.yml文件

[root@node1 prometheus]# vi /home/prometheus/opt/prometheus/prometheus.yml
global:scrape_interval:     60sevaluation_interval: 60s
scrape_configs:- job_name: prometheusstatic_configs:- targets: ['192.168.0.201:9190'] # 采取prometheus指标数据labels:instance: prometheus- job_name: linuxstatic_configs:- targets: ['192.168.0.201:9100'] # 采取本地指标数据labels:instance: localhost

2、启动

docker run -d -p 9190:9090 --name prometheus -v /home/prometheus/opt/prometheus:/etc/prometheus prom/prometheus

http://192.168.0.201:9190/

img

三、启动webhook-dingtalk

docker run -d -p 8060:8060 --name webhook timonwong/prometheus-webhook-dingtalk

1、查询webhook映射,进入容器内修改配置文件

[root@node1 prometheus]# docker inspect webhook|grep Dir

img

2、进入mergerDir

[root@node1 prometheus]# cd /home/docker/overlay2/52933d06cee0e5135bf0bfc5907a581f8b19a480688af08d1c2b7ff2a8239e96/merged

3、进入配置文件夹

[root@node1 merged]# cd etc/prometheus-webhook-dingtalk/

4、修改配置文件

[root@node1 prometheus-webhook-dingtalk]# vi config.yml
## Request timeout
# timeout: 5s## Uncomment following line in order to write template from scratch (be careful!)
#no_builtin_template: true## Customizable templates path
#templates:
#  - contrib/templates/legacy/template.tmpl## You can also override default template using `default_message`
## The following example to use the 'legacy' template from v0.3.0
#default_message:
#  title: '{{ template "legacy.title" . }}'
#  text: '{{ template "legacy.content" . }}'## Targets, previously was known as "profiles"
targets:webhook1:url: https://oapi.dingtalk.com/robot/send?access_token=ed49*************************7239514b010270f# secret for signaturesecret: SEC**********************webhook2:url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxwebhook_legacy:url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxx# Customize template contentmessage:# Use legacy templatetitle: '{{ template "legacy.title" . }}'text: '{{ template "legacy.content" . }}'webhook_mention_all:url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxmention:all: truewebhook_mention_users:url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxmention:mobiles: ['156xxxx8827', '189xxxx8325']
~

5、重启webhook

[root@node1 prometheus-webhook-dingtalk]# docker restart webhook

6、查看webhook日志

[root@node1 prometheus-webhook-dingtalk]# docker logs webhook

img

复制webhook1地址

四、启动alertmanager

1、创建alertmanager.yml映射

[root@node1 /]# sudo mkdir /home/alertmanager/opt/alertmanager/
[root@node1 /]# cd /home/alertmanager/opt/alertmanager/
[root@node1 alertmanager]# vi alertmanager.yml
global:resolve_timeout: 5mroute: # 告警路由配置,定义如何处理和发送告警receiver: webhookgroup_wait: 30sgroup_interval: 1mrepeat_interval: 4hgroup_by: [alertname]routes:- receiver: webhookgroup_wait: 10sreceivers: # 告警接收者配置,定义如何处理和发送告警
- name: webhookwebhook_configs:- url: http://192.168.0.201:8060/dingtalk/webhook1/send  # 告警 Webhook URLsend_resolved: true # 是否发送已解决的告警。如果设置为 true,则在告警解决时发送通知

注意webhook的url是前面webhookq启动日志里有的地址。将localhost改成服务器对应的ip即可。

2、修改prometheus.yml文件

[root@node1 alertmanager]# vi /home/prometheus/opt/prometheus/prometheus.yml
global:scrape_interval:     60sevaluation_interval: 60s
# Alertmanager配置
alerting:alertmanagers:- static_configs:- targets: ["192.168.0.201:9093"]
# rule配置
rule_files:- "/etc/prometheus/rules.yml"
scrape_configs:- job_name: prometheusstatic_configs:- targets: ['192.168.0.201:9190'] # 采取prometheus指标数据labels:instance: prometheus- job_name: linuxstatic_configs:- targets: ['192.168.0.201:9100'] # 采取本地指标数据labels:instance: localhost

3、启动

docker run -d -p 9093:9093 -v /home/alertmanager/opt/alertmanager/:/etc/alertmanager/ --name alertmanager prom/alertmanager

http://192.168.0.201:9093/

img

五、配置预警规则

[root@node1 alertmanager]# vi /home/prometheus/opt/prometheus/rules.yml
groups:- name: host_monitoringrules:- alert: 内存报警expr: netdata_system_ram_MiB_average{chart="system.ram",dimension="free",family="ram"} < 800for: 2mlabels:team: nodeannotations:Alert_type: 内存报警Server: '{{$labels.instance}}'#summary: "{{$labels.instance}}: High Memory usage detected"explain: "内存使用量超过90%,目前剩余量为:{{ $value }}M"#description: "{{$labels.instance}}: Memory usage is above 80% (current value is: {{ $value }})"- alert: CPU报警expr: netdata_system_cpu_percentage_average{chart="system.cpu",dimension="idle",family="cpu"} < 20for: 2mlabels:team: nodeannotations:Alert_type: CPU报警Server: '{{$labels.instance}}'explain: "CPU使用量超过80%,目前剩余量为:{{ $value }}"#summary: "{{$labels.instance}}: High CPU usage detected"#description: "{{$labels.instance}}: CPU usage is above 80% (current value is: {{ $value }})"- alert: 磁盘报警expr: netdata_disk_space_GiB_average{chart="disk_space._",dimension="avail",family="/"} < 4for: 2mlabels:team: nodeannotations:Alert_type: 磁盘报警Server: '{{$labels.instance}}'explain: "磁盘使用量超过90%,目前剩余量为:{{ $value }}G"- alert: 服务告警expr: up == 0for: 2slabels:team: nodeannotations:Alert_type: 服务报警summary: 'instance {{$labels.instance}} down'description: "netdata服务已关闭"

六、重启prometheus

[root@node1 alertmanager]# docker restart prometheus

七、测试

[root@node1 alertmanager]# docker stop node-exporter

img

ps:通知内容待优化。。。

八、启动gafana

docker run -d -p 3000:3000 --name=grafana grafana/grafana

http://192.168.0.201:3000/

admin/admin

第一次登陆需要修改密码

img

1、设置数据源

img

img

img

2、设置dashboards

img

填入 https://grafana.com/grafana/dashboards/405 点击load,即可下载Node-Exporter的dashboard

参考文章:

docker部署prometheus+grafana+alertmanager+dingtalk实现钉钉告警_prometheus钉钉告警_生夏夏夏的博客-CSDN博客

docker部署prometheus告警钉钉通知_POI操作Excel的技术博客_51CTO博客

Rancher

修改密码:

docker exec -ti rancher reset-password

https://blog.csdn.net/jiumingmao1991/article/details/124733879

Harbor

Harbor重置密码

1、进入容器

docker exec -it harbor-db /bin/bash

2、登录数据库

psql -h postgresql -d postgres -U postgres      #默认密码为root123

3、进入 registry库

\c registry

4、查看用户表

select * from harbor_user;

5、修改用户密码

update harbor_user set password='c999cbeae74a90282c8fa7c48894fb00', salt='nmgxu7a5ozddr0z6ov4k4f7dgnpbvqky' where username='admin';

6、使用默认密码Harbor12345登录

Docker容器:docker推送镜像至Harbor

1、Harbor创建项目

2、进入test项目,查看推送命令

3、在docker服务器上准备一个镜像

4、修改docker客户端配置

5、重启docker服务

6、docker登录Harbor

7、docker镜像推送到Harbor

1、Harbor创建项目

img

2、进入test项目,查看推送命令

img

3、在docker服务器上准备一个镜像

docker pull nginxdocker tag nginx 192.168.2.34:23000/test/nginx:latest

img

4、修改docker客户端配置

vi /etc/docker/daemon.json{"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],"insecure-registries": ["http://192.168.2.34:23000"]
}

其中:

registry-mirrors配置的是加速镜像源。
insecure-registries配置就是Harbor的仓库地址。
常见的加速镜像源有:

腾讯云:https://mirror.ccs.tencentyun.com
七牛云:https://reg-mirror.qiniu.com
网易云:https://hub-mirror.c.163.com
DaoCloud:http://f1361db2.m.daocloud.io
科大镜像:https://docker.mirrors.ustc.edu.cn
5、重启docker服务

systemctl daemon-reload
systemctl restart docker

6、docker登录Harbor

img

7、docker镜像推送到Harbor

img

img

Harbor 本地docker镜像仓库远程连接(镜像管理零距离!!)

简单几步,实现本地Harbor docker镜像仓库结合cpolar内网穿透实现远程推送和拉取镜像

1. 查看本地镜像

进入本地 Harbor docker 仓库,我们可以看到我们的本地镜像,这边方便测试,提前上传了一个镜像

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在左侧可以看到推送命令,这里局域网ip没有出现端口,说明默认使用80端口,知道了端口,我们下面设置cpolar公网地址

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 安装cpolar

上面我们在本地 Linux中查看了Harbor 里面的本地docker镜像,下面我们在Linux中安装cpolar内网穿透工具,通过cpolar的http公网地址,我们可以很容易实现远程连接Harbor中的镜像,并进行推送和下载,而无需自己注册域名购买云服务器.下面是安装cpolar步骤

cpolar官网地址: https://i.cpolar.com/m/56Ju (进入官网注册免费账号)

  • 使用一键脚本安装命令
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash
  • 向系统添加服务
sudo systemctl enable cpolar
  • 启动cpolar服务
sudo systemctl start cpolar

cpolar安装成功后,在外部设备通过浏览器上访问Linux 的9200端口即:【http://局域网ip:9200】,即可看到cpolar 管理界面.然后使用cpolar账号登录。

20230130105810

3. 配置公网连接地址

点击左侧仪表盘的隧道管理——创建隧道,创建一个我们上面看到的80端口的隧道!

  • 隧道名称:可自定义命名,注意不要与已有的隧道名称重复
  • 协议:选择http
  • 本地地址:80 (Harbor默认端口,具体以自己的端口为准)
  • 域名类型:免费选择随机域名
  • 地区:选择China vip

点击创建

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

隧道创建成功后,点击左侧的状态——在线隧道列表,查看所生成的公网地址,有两种访问方式,一种是http 和https

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4. 远程拉取镜像测试

上面我们创建了Harbor的公网地址,接下来使用cpolar公网地址将我们本地的docker镜像下载下来.

首先需要登录Harbor(这里的Harbor版本是最新的,登录比较容易,不会出现异常),输入命令:

docker login 公网地址 -u 用户名

然后提示输入密码,登录后,出现succeeded 表示登录成功!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后拉取我们本地镜像,进入本地镜像仓库,复制拉取命令

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下是本例子复制的拉取命令(实际以自己的为准),我们只需要把前面局域网IP地址换成cpolar公网地址即可, 注意!!! 协议名称http://不需要输入

docker pull     
28395150.r3.vip.cpolar.cn/library/ghcr.io/lissy93/dashy@sha256:134b0c09c4d199e53c78a81fc07173a314bd63833da4a5afc47caadc72fe582c

然后执行拉取,拉取后,查看docker镜像列表,即可看到我们拉取的镜像,表示成功!!,这样一个远程的连接就设置好了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5. 远程推送镜像测试

同样,远程推送也是,我们使用公网地址进行远程推送镜像到本地仓库,首先查看我们镜像ID

docker images

查看我们需要推送的镜像ID,这里演示把tomcat镜像推送到本地仓库

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

先标记镜像

docker tag 镜像ID cpolar公网地址/Harbor上的项目名称/镜像名称

执行后,输入推送命令

docker push cpolar公网地址/Harbor上的项目名称/镜像名称

执行后,我们等待上传,这里使用的是cpolar公网地址,所以有带宽限制,可以使用cpolar中NAS套餐,带宽大一些,速度快一些!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

推送上传成功后,我们打开本地的Harbor 镜像仓库,即可看到我们远程上传的tomcat镜像,表示上传成功!!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改Cpolar Web UI默认端口号

如您本地已有服务使用了9200端口,那么您可以将cpolar web UI管理端口修改为其他端口,如127.0.0.1:9300

1. 找到cpolar配置文件

  • windows系统: c:\Users\用户名.cpolar\cpolar.yml,右键点击“打开方式”——“记事本”,选择使用记事本打开
  • linux系统:执行命令nano /usr/local/etc/cpolar/cpolar.yml

2. 在配置文件中,增加一行参数:

client_dashboard_addr: 127.0.0.1:9300

Bash

Copy

注:添加的一行,与authtoken是一个级别的参数。

3. 保存cpolar配置文件
4. 重启cpolar服务

  • windows系统:在控制面板–管理工具—服务—cpolar service,重启服务。
  • linux系统:执行命令sudo systemctl restart cpolar

5. 浏览器访问本地9300端口http://127.0.0.1:9300/

20221213144331

Apifox

Nacos

tar.gz安装启动

1、下载压缩包

wget https://github.com/alibaba/nacos/releases/download/1.2.1/nacos-server-1.2.1.tar.gz

2、解压压缩包

tar -zxvf  nacos-server-1.2.1.tar.gz

3、进入nacos目录

cd /mnt/nacos-1.2.1/nacos/bin

4、启动nacos服务

sh startup.sh -m standalone
#或者
./startup.sh -m standalone

[INFO] nacos-api 2.3.1-SNAPSHOT … SUCCESS [ 20.941 s]
[INFO] nacos-common 2.3.1-SNAPSHOT … SUCCESS [ 27.461 s]
[INFO] nacos-consistency 2.3.1-SNAPSHOT … SUCCESS [ 14.950 s]
[INFO] nacos-datasource-plugin 2.3.1-SNAPSHOT … SUCCESS [ 4.327 s]
[INFO] nacos-custom-environment-plugin 2.3.1-SNAPSHOT … SUCCESS [ 1.260 s]
[INFO] nacos-sys 2.3.1-SNAPSHOT … SUCCESS [ 5.294 s]
[INFO] nacos-persistence 2.3.1-SNAPSHOT … SUCCESS [ 4.658 s]
[INFO] nacos-auth-plugin 2.3.1-SNAPSHOT … SUCCESS [ 1.917 s]
[INFO] nacos-auth 2.3.1-SNAPSHOT … SUCCESS [ 5.680 s]
[INFO] nacos-trace-plugin 2.3.1-SNAPSHOT … SUCCESS [ 1.428 s]
[INFO] nacos-control-plugin 2.3.1-SNAPSHOT … SUCCESS [ 5.069 s]
[INFO] nacos-core 2.3.1-SNAPSHOT … SUCCESS [ 16.177 s]
[INFO] nacos-encryption-plugin 2.3.1-SNAPSHOT … SUCCESS [ 0.777 s]
[INFO] nacos-config-plugin 2.3.1-SNAPSHOT … SUCCESS [ 0.955 s]
[INFO] nacos-config 2.3.1-SNAPSHOT … SUCCESS [ 16.215 s]
[INFO] nacos-cmdb 2.3.1-SNAPSHOT … SUCCESS [ 1.049 s]
[INFO] nacos-naming 2.3.1-SNAPSHOT … SUCCESS [ 24.958 s]
[INFO] nacos-address 2.3.1-SNAPSHOT … SUCCESS [ 6.971 s]
[INFO] nacos-client 2.3.1-SNAPSHOT … SUCCESS [ 21.000 s]
[INFO] nacos-default-auth-plugin 2.3.1-SNAPSHOT … SUCCESS [ 11.854 s]
[INFO] nacos-default-control-plugin 2.3.1-SNAPSHOT … SUCCESS [ 1.692 s]
[INFO] nacos-default-plugin-all … SUCCESS [ 0.698 s]
[INFO] nacos-istio 2.3.1-SNAPSHOT … SUCCESS [ 31.199 s]
[INFO] nacos-prometheus 2.3.1-SNAPSHOT … SUCCESS [ 3.616 s]
[INFO] nacos-console 2.3.1-SNAPSHOT … SUCCESS [ 6.096 s]
[INFO] nacos-config-test 2.3.1-SNAPSHOT … SUCCESS [ 3.734 s]
[INFO] nacos-naming-test 2.3.1-SNAPSHOT … SUCCESS [ 3.951 s]
[INFO] nacos-core-test 2.3.1-SNAPSHOT … SUCCESS [ 3.782 s]
[INFO] nacos-test 2.3.1-SNAPSHOT … SUCCESS [ 1.108 s]
[INFO] nacos-example 2.3.1-SNAPSHOT … SUCCESS [ 2.315 s]
[INFO] nacos-distribution 2.3.1-SNAPSHOT … SUCCESS [ 1.496 s]
[INFO] nacos-plugin 2.3.1-SNAPSHOT … SUCCESS [ 0.653 s]
[INFO] nacos-plugin-default-impl 2.3.1-SNAPSHOT … SUCCESS [ 0.438 s]
[INFO] Alibaba NACOS 2.3.1-SNAPSHOT … SUCCESS [ 2.099 s]

Nacos用做配置中心时启动报错SocketTimeoutException http://localhost:8848

当使用nacos作为注册中心时,很顺利,进如下配置(仅仅配置了ip和端口)

启动类加@EnableDiscoveryClient注解

nacos作为配置中心
当继续将nacos作为配置中心时
添加加依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

改配置

控制台添加了与项目同名的配置

启动项目后报错
如下:

ERROR 16160 — [ main] c.a.n.c.config.http.ServerHttpAgent : [NACOS SocketTimeoutException httpGet] currentServerAddr:http://localhost:8848
1
看样子是连不上nacos,而且连的是localhost:8848,我明明配置的是ip:8848,为何没用?
查阅官网资料后发现配置的不对,nacos需要在bootstrap.yml或bootstrap.properties进行配置,没在这配置默认配的http://localhost:8848

spring:
nacos-host: 47.99.123.209
nacos-port: 8848
main:

allow-bean-definition-overriding: true

application:

name: mall-member

cloud:

nacos:discovery:server-addr: ip:8848userName: "nacos"password: "nacos"config:server-addr: ip:8848userName: "nacos"password: "nacos"file-extension: properties

Linux

常用软件:

wget
 yum install wget
rsync 远程同步工具

基本语法:

rsync -rvl $pdir/$fname $user@$host:$pdir/$fname 

安装命令:

yum install -y rsync

rsync -rvl /opt/lagou/software/ root@192.168.1.115:/opt/lagou/software

git
 yum install git

SonarQube

Docker搭建SonarQube服务 - Linux
本文介绍如何在Linux服务器上使用docker简便并快速的搭建SonarQube服务。

参考文档:
Prerequisites and Overview|SonarQube Docs
Installing SonarQube from the Docker Image | SonarQube Docs

本文使用的镜像版本:
docker.io/postgres:12-alpine - sonarqube数据存储服务镜像
docker.io/sonarqube:8.9.0-community - sonarqube的社区版镜像

先决条件:
运行SonarQube的唯一先决条件是在计算机上安装Java(Oracle JRE 11或OpenJDK 11)。

安装jdk11
yum install java-11-openjdk

硬件要求
SonarQube 服务器的小规模(个人或小型团队)实例至少需要 2GB 的 RAM 才能高效运行,并且需要 1GB 的可用 RAM 用于操作系统。如果您要为大型团队或企业安装实例,请考虑以下其他建议。
您需要的磁盘空间量将取决于您使用 SonarQube 分析的代码量。
SonarQube必须安装在具有出色读写性能的硬盘驱动器上。最重要的是,“data”文件夹包含Elasticsearch索引,当服务器启动并运行时,将在其上完成大量的I / O。因此,出色的读写硬盘性能将对SonarQube服务器的整体性能产生重大影响。
SonarQube 不支持服务器端的 32 位系统。但是,SonarQube确实在扫描仪端支持32位系统。

Docker-compose安装Sonar服务
Linux安装docker与docker-compose-plugin

yum install docker   # 安装docker
yum install docker-compose-plugin  # 安装docker-compose-plugin
docker-compose version

如果dokcer-compose-plugin安装完成后,提示docker-compose命令不存在,需要查找插件安装的位置,然后创建软连接/usr/bin/docker-compose
示例:ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose
Install the Compose plugin | Docker Docs

创建docker-compose.yml

文件内容如下:

version: "3"services:sonarqube:image: sonarqube:8.9.0-communitycontainer_name: sonarqube-8.9depends_on:- dbenvironment:SONAR_JDBC_URL: jdbc:postgresql://postgres-12:5432/sonarSONAR_JDBC_USERNAME: sonarSONAR_JDBC_PASSWORD: sonarvolumes:- sonarqube_data:/opt/sonarqube/data- /opt/sonarqube/extensions:/opt/sonarqube/extensions- /opt/sonarqube/logs:/opt/sonarqube/logs- /opt/sonarqube/conf:/opt/sonarqube/confports:- "9000:9000"db:image: postgres:12-alpinecontainer_name: postgres-12environment:POSTGRES_USER: sonarPOSTGRES_PASSWORD: sonarvolumes:- postgresql_data:/var/lib/postgresql/dataports:- "5432:5432"volumes:sonarqube_data:postgresql_data:

创建并启动容器

docker-compose -f docker-compose.yml up -d

参考命令
启动服务

docker-compose -f docker-compose.yml start 

停止服务

docker-compose -f docker-compose.yml stop 

重启服务

docker-compose -f docker-compose.yml restart 

首次登录sonar服务用户名和密码:admin/admin。强制需要修改密码。

安装汉化插件
在线安装
管理员登录soanr服务,导航到配置>应用市场>插件 ,搜索Chinese ,找到Chinese Pack,点击右侧安装按钮进行在线安装,在线安装会比较慢,安装完成需要重启项目。

线下安装
也可以选择线下手动安装。点击首页链接,进入github项目页面,点击Release,搜索对应的版本进行下载。

下载完成后,讲文件上传到服务器,放到容器内的/opt/sonarqube/extensions/plugins目录下,然后重启服务。
docker-compose.yml文件中,将容器的/opt/sonarqube/extensions目录挂载的宿主机的/opt/sonarqube/extensions目录,所以将插件jar包放到宿主机的/opt/sonarqube/extensions/plugins即可。

docker run --name db -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -p 5432:5432 -v /opt/postgresql/data:/opt/postgresql/data -d postgres:12-alpine
docker run --name sonar --link db -e SONARQUBE_JDBC_URL=jdbc:postgresql://192.168.1.113:5432/sonar -e SONARQUBE_JDBC_USERNAME=sonar -e SONARQUBE_JDBC_PASSWORD=sonar -p 9090:9090 -d sonarqube
Sonarqube扫描原理

SonarQube的扫描原理主要包括以下步骤:

  1. 源代码收集:SonarQube支持多种代码托管系统,如Git、SVN等,允许用户配置项目仓库地址以自动获取源代码。
  2. 语言解析:SonarQube能够处理多种编程语言,并将源代码转换成抽象语法树(AST),以便更有效地分析和理解代码。
  3. 指标计算:在这个阶段,SonarQube会根据代码的不同度量指标,如代码覆盖率、代码复杂度和代码重复率,评估代码质量和可维护性。
  4. 问题检测:SonarQube结合了语法和语义分析,以及内置的规则集,来检测代码中的潜在问题和违反编码规范的情况。
  5. 问题汇总:一旦检测到问题,SonarQube会将其汇总和分类,形成包含问题详细描述、位置和修复建议的完整代码质量报告。
  6. 持续集成:SonarQube可以与其他持续集成/持续部署(CI/CD)工具集成,实现代码质量的持续监测,并在代码提交时自动触发扫描和分析过程。
  7. 持续分析:SonarQube不仅可以进行单次扫描,还支持持续分析,即在代码提交或构建过程中自动进行代码质量的检查。

综上所述,SonarQube的扫描原理涉及到代码的收集、解析、指标的计算、问题的检测和问题的汇总,最终通过持续集成和持续分析来实现对代码质量的持续监控和管理

Zabbix

Docker安装启动

  • 下载zabbix/zabbix-appliance镜像
docker pull zabbix/zabbix-appliance:latest
  • 启动容器,要先确保端口没被占用
 docker run --name zabbix-app -t -d\-p 5231:80 -p 10051:10051\-v zabbix_data:/var/lib/mysql\-v /etc/timezone:/etc/timezone \-v /etc/localtime:/etc/localtime \-e PHP_TZ="Asia/Shanghai"\zabbix/zabbix-appliance
  • 查看是否运行
docker ps
  • 在浏览器中输入虚拟机ip:5231,访问zabbix面板

  • 初始账户密码:Admin zabbix

[zabbix-Get value from agent failed: cannot connect to [127.0.0.1]:10050]: [111] Connection refused

问题描述:

img

监控zabbix服务端这台服务器,然后显示Get value from agent failed: cannot connect to [[127.0.0.1]:10050]: [111] Connection refused

看到agent然后又看到10050端口

直接telnet语句去检测

第一种:端口不通

解决方法:

1、a``gent端的ip为192.168.85.11,``server端的ip为192.168.85.11

#本地电脑WIN7系统,执行语句 telnet 192.168.85.11 10051 查看agent端口是否开启

img

#本地电脑WIN7系统,执行语句 telnet 192.168.85.11 10050 查看server端口是否开启

img

#可以看到是10050这个端口不通,然后回到服务端查看agent服务状态,看到原来没开启服务原因

img

#开启agent服务

img

#然后就没有报错了!

ps -ef | grep zabbix-agent 看是否有zabbix-agent的进程。

img

#再配置一下开机自启动agent服务

systemctl enable zabbix-agent.service

Traefix

Linux Traefik 工具 dashboard远程访问

前言

Træfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件,能轻易的部署微服务。它支持多种后端 (Docker, Swarm, Mesos/Marathon, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) , 可以对配置进行自动化、动态的管理.

Træfɪk 支持docker一键部署,内置 Web UI,管理相对方便,下面介绍Linux 本地 docker 一键部署 traefik +cpolar 内网穿透工具实现远程访问Træfɪk Web UI 管理界面!

1. Docker 部署 Træfɪk

在任意目录,创建一个名称为 docker-compose.yml文件

vim docker-compose.yml

把下面参数复制 进去,本例主要目的是演示如何远程访问Træfɪk dashboard 界面,如果需要更复杂的配置,可以参考官方文档进行详细参数配置!

version: "3"services:traefik:image: traefik:v3.0.0-beta3ports:- 8080:8080command: "--api=true --api.dashboard=true --api.insecure=true"

tips: 上面参数挂载到宿主机8080端口,如需修改其他端口,可以自行修改,这里默认使用8080

img

输入完成后,保存配置文件,然后执行docker compose up,进行部署,如果卡在上述界面,可以先Ctrl+C退出,然后输入docker ps -a查询出traefik 容器ID,然后使用docker start 容器ID命令启动即可

img

启动成功后,输入docker ps 命令即可看到运行的traefik 容器

img

2. 本地访问traefik测试

本地部署完成后,我们在局域网设备中通过局域网方式访问Linux 8080 端口,即可看到traefik deshboard 界面, 本地访问就成功了,下面安装cpolar 内网穿透工具,实现远程访问

img

3. Linux 安装cpolar

上面在本地Linux中成功部署了Traefik,并局域网访问ok,下面我们在Linux安装cpolar内网穿透工具,通过cpolar 转发本地端口映射的http公网地址,我们可以很容易实现远程访问,而无需自己注册域名购买云服务器.下面是安装cpolar步骤

cpolar官网地址: https://www.cpolar.com

  • 使用一键脚本安装命令
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash
  • 向系统添加服务
sudo systemctl enable cpolar
  • 启动cpolar服务
sudo systemctl start cpolar

cpolar安装成功后,在外部浏览器上访问Linux 的9200端口即:【http://局域网ip:9200】,使用cpolar账号登录,登录后即可看到cpolar web 配置界面,结下来在web 管理界面配置即可

img

4. 配置Traefik公网访问地址

点击左侧仪表盘的隧道管理——创建隧道,创建一个Traefik的cpolar 公网地址隧道!

  • 隧道名称:可自定义命名,注意不要与已有的隧道名称重复
  • 协议:选择http
  • 本地地址:8080 (局域网访问的端口)
  • 域名类型:免费选择随机域名
  • 地区:选择China

点击创建

img

隧道创建成功后,点击左侧的状态——在线隧道列表,查看所生成的公网访问地址,有两种访问方式,一种是http 和https

img

5. 公网远程访问Traefik

使用上面的cpolar https公网地址,在任意设备的浏览器进行访问,即可成功看到我们Traefik dashboard界面,这样一个公网地址且可以远程访问就创建好了,使用了cpolar的公网域名,无需自己购买云服务器,即可发布到公网进行远程访问,后续Traefik设置方法,可以参考官方文档进行学习!

img

6. 固定Traefik公网地址

由于以上使用cpolar所创建的隧道使用的是随机公网地址,24小时内会随机变化,不利于长期远程访问。因此我们可以为其配置二级子域名,该地址为固定地址,不会随机变化【ps:http://cpolar.cn已备案】

注意需要将cpolar套餐升级至基础套餐或以上,且每个套餐对应的带宽不一样。【http://cpolar.cn已备案】

登录cpolar官网,点击左侧的预留,选择保留二级子域名,设置一个二级子域名名称,点击保留,保留成功后复制保留的二级子域名名称

img

保留成功后复制保留成功的二级子域名的名称

img

返回登录cpolar web UI管理界面,点击左侧仪表盘的隧道管理——隧道列表,找到所要配置的隧道,点击右侧的编辑

img

修改隧道信息,将保留成功的二级子域名配置到隧道中

  • 域名类型:选择二级子域名
  • Sub Domain:填写保留成功的二级子域名

点击更新(注意,点击一次更新即可,不需要重复提交)

img

更新完成后,打开在线隧道列表,此时可以看到公网地址已经发生变化,地址名称也变成了固定的二级子域名名称的域名

img

最后,我们使用固定的公网地址访问,可以看到访问成功,这样一个固定且永久不变的公网地址就设置好了,随时随地都可以远程访问Traefik界面,提高工作效率!!

img

转载自cpolar极点云文章:Linux Traefik 工具 Dashboard远程访问

Graylog

DockerCompose 一键部署graylog

docker-compose配置参考:https://docs.graylog.org/en/3.3/pages/installation/docker.html

# docker-compose配置参考:https://docs.graylog.org/en/3.3/pages/installation/docker.html
version: '3'services:mongo:image: mongo:3container_name: graylog_demo_mongorestart: unless-stopped#    volumes:#      - ./graylog/mongo_data:/data/dbnetworks:- graylogelasticsearch:image: elasticsearchcontainer_name: graylog_demo_elasticsearchrestart: unless-stopped#    volumes:#      - ./graylog/es_data:/usr/share/elasticsearch/dataenvironment:- http.host=0.0.0.0- transport.host=localhost- network.host=0.0.0.0- "ES_JAVA_OPTS=-Xms512m -Xmx512m"ulimits:memlock:soft: -1hard: -1deploy:resources:limits:memory: 1gnetworks:- grayloggraylog:image: graylog/graylog:3.3container_name: graylog_demo_graylogrestart: unless-stopped#    volumes:#      - ./graylog/graylog_data_journal:/usr/share/graylog/data/journalenvironment:- GRAYLOG_PASSWORD_SECRET=somepasswordpepper # CHANGE ME (must be at least 16 characters)!- GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 # Password: admin- GRAYLOG_HTTP_EXTERNAL_URI=http://www.zhengqingya.com:9001/ # TODO 这里填写自己的ip地址ports:# Graylog web interface and REST API- 9001:9000# Syslog TCP- 1514:1514# Syslog UDP- 1514:1514/udp# GELF TCP- 12201:12201# GELF UDP- 12201:12201/udpnetworks:- graylogdepends_on:- mongo- elasticsearch# 网桥graylog -> 方便相互通讯
networks:graylog:driver: bridge

创建上面的文件为docker-compose.yml,然后直接启动就可以

docker-compose -f docker-compose-graylog.yml -p graylog_demo up -d

访问地址为 localhost:9001, 默认登录账号密码:admin/admin

Gitlab

代码分析工具

有几个常用的Java源码扫描工具可以帮助您进行源代码分析和检查。以下是其中一些工具:

FindBugs:FindBugs是一个静态分析工具,用于查找Java代码中的潜在缺陷和错误。它可以检测出空指针引用、资源未关闭、不良的代码实践等问题。FindBugs已经停止维护,但仍然是一个常用的工具。
PMD:PMD是另一个流行的静态代码分析工具,用于检测Java代码中的潜在问题和不良实践。它可以检查代码中的重复代码、未使用的变量、低效的代码等。
Checkstyle:Checkstyle是一个用于强制执行编码规范的工具,它可以确保代码符合一致的样式和规范。它可以检查代码缩进、命名约定、注释规范等。
SonarQube:SonarQube是一个功能强大的代码质量管理平台,可以对Java代码进行静态分析,并提供详细的代码质量指标和报告。它整合了多个静态分析工具,包括FindBugs、PMD和Checkstyle等。
这些工具可以作为独立的命令行工具使用,也可以与集成开发环境(IDE)或持续集成(CI)工具集成,以便在开发过程中自动执行代码扫描和检查。

请注意,这些工具都有自己的配置和规则集,您可以根据项目的需求进行自定义配置。此外,这些工具只能检测到一部分潜在问题,仍然需要开发人员进行代码审查和测试来确保代码质量。

建议您根据项目的具体需求选择适合的工具,并根据项目的要求进行配置和使用。

可视化工具

ES集群可视化管理工具-Cerebro

文章目录

      • \1. Cerebro简介
      • \2. 环境要求
      • \3. Cerebro安装
      • \4. 访问Cerebro
      • \5. 面板介绍
      • \6. LDAP集成
      • \7. Docker方式安装

1. Cerebro简介

Cerebro是一个开源(MIT许可)Elasticsearch web管理工具,使用Scala、Play框架、AngularJS和Bootstrap构建。

GitHub地址:https://github.com/lmenezes/cerebro

2. 环境要求

软件环境:Cerebro需要Java 1.8或更高版本才能运行。
硬件配置推荐:4C 8G 500G,俄一般会和Kibana部署在同一台机器

3. Cerebro安装

从https://github.com/lmenezes/cerebro/releases下载最新安装包,本文档采用rpm方式安装,文末会有docker容器化部署介绍。

1、准备基础环境
yum install java -y
wget https://github.com/lmenezes/cerebro/releases/download/v0.9.2/cerebro-0.9.2-1.noarch.rpm
[root@kibana-164 /opt]# rpm -ivh cerebro-0.9.2-1.noarch.rpm
2、修改配置文件
~]# vim /etc/cerebro/application.conf 
data.path = "/tmp/cerebro.db"			#更改数据路径3、启动cerebro
[root@kibana ~]# systemctl start cerebro
[root@kibana ~]# systemctl enable cerebro4、检查端口?
cerebro侦听(默认为0.0.0.0:9000)
[root@kibana-164 ~]# lsof -i:9000
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    1676 cerebro  130u  IPv6  22234      0t0  TCP *:cslistener (LISTEN)补充其他方式启动:
bin/cerebro -Dhttp.port=1234 -Dhttp.address=127.0.0.1

4. 访问Cerebro

http://IP:9000

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5. 面板介绍

集群名称:my-es
节点数:3 nodes
索引数:8 indices
分片数:16 shards
文档数:34 docs
磁盘使用量:21.08M

6. LDAP集成

LDAP可以使用环境变量进行配置。如果通常使用docker运行cerebro,则可以传递包含所有env var的文件。该文件如下所示

#将其设置为ldap以激活ldap授权
AUTH_TYPE = ldap#您的ldap网址
LDAP_URL = ldap://exammple.com:389LDAP_BASE_DN = OU =用户,DC =示例,DC = com#通常方法应为“简单”,否则,将其设置为SASL机制
LDAP_METHOD =简单#用户模板执行string.format()操作,其中
先传入#用户名,然后传入base-dn。一些实例
#   - %S =>假用户原封不动
#   - %s@domain.com =>追加“@ domain.com”到用户名
#   - UID =%S,%S =>通常的OpenLDAP的情况下
LDAP_USER_TEMPLATE=%s@example.com#可以执行搜索的用户标识符
LDAP_BIND_DN=admin@example.com
LDAP_BIND_PWD =管理员密码#组成员资格设置(可选)#如果未设置将使用LDAP_BASE_DN 
# LDAP_GROUP_BASE_DN = OU =用户,DC =示例,DC = com#代表用户的属性,例如uid或mail 
# LDAP_USER_ATTR = mail#如果未设置,将使用
LDAP_USER_TEMPLATE # LDAP_USER_ATTR_TEMPLATE =%s#用于测试组成员资格的过滤器。如果该属性是空的,则没有组成员资格检查
# AD示例=>的memberOf = CN = MYGROUP,OU = ouofthegroup,DC =域,DC = COM 
# OpenLDAP的例子=> CN = MYGROUP 
# LDAP_GROUP =的memberOf =的memberOf = CN = mygroup,ou =该组的其他人,DC =域,DC = com

7. Docker方式安装

docker run -p 9000:9000 lmenezes/cerebro

也可以在官方docker hub仓库中找到官方docker映像。

docker run -p 9000:9000 --env-file env-ldap lmenezes/cerebro #可进行传参
可根据自己实际需求制作Docker镜像~
FROM openjdk:11-jre-slim
ENV CEREBRO_VERSION 0.9.2RUN  apt-get update \&& apt-get install -y wget \&& rm -rf /var/lib/apt/lists/* \&& mkdir -p /opt/cerebro/logs \&& wget -qO- https://github.com/lmenezes/cerebro/releases/download/v${CEREBRO_VERSION}/cerebro-${CEREBRO_VERSION}.tgz \| tar xzv --strip-components 1 -C /opt/cerebro \&& sed -i '/<appender-ref ref="FILE"\/>/d' /opt/cerebro/conf/logback.xml \&& addgroup -gid 1000 cerebro \&& adduser -gid 1000 -uid 1000 cerebro \&& chown -R cerebro:cerebro /opt/cerebroWORKDIR /opt/cerebro
USER cerebroENTRYPOINT [ "/opt/cerebro/bin/cerebro" ]

zkui:好用的zookeeper ui工具

1 说明

1.1 项目地址

https://github.com/DeemOpen/zkui

1.2 安装方式

maven编译后,java控制台启动

1.3 准备事项
  • 安装好JDK 7.0+,配置好JAVA_HOME。(java命令可用即可:java -version)
  • 安装好MAVEN,配置好M2_HOME。(mvn命令可用即可: mvn -version)
  • 已经安装了一个zookeeper。《Zookeeper安装》看这里。(默认地址和端口: localhost:2181)
  • 下载zkui源码zip包,并解压到目录C:\,获得解压后路径:C:\zkui-master。(zkui与zookeeper安装在同一台设备上)

2 编译

cd C:\zkui-mastermvn clean package

3 启动

将C:\zkui-master\config.cfg(模块可用,也可以根据需要进行修改)拷贝到C:\zkui-master\target目录下(config.cfg与zkui-xx.jar文件同目录即可)。

zkui与zookeeper安装在同一台设备上,所以config.cfg不用任何修改就能够使用。如果不在同一台设备上,需要修改config.cfg文件。

java -jar target/zkui-2.0-SNAPSHOT-jar-with-dependencies.jar

4 访问控制台

http://localhost:9090

username: admin, pwd: manager (Admin privileges, CRUD operations supported)

username: appconfig, pwd: appconfig (Readonly privileges, Read operations supported)

img

5 其它

linux下运行:

nohup java -jar zkui-2.0-SNAPSHOT-jar-with-dependencies.jar &

Linux 安装禅道

一.下载禅官网:https://www.zentao.net/download/zentaopms18.3-82231.html

img

linux中下载

wget https://www.zentao.net/dl/zentao/18.3/ZenTaoPMS.18.3.zbox_64.tar.gz

(之前很早下载过所以和上面显示的版本比相同)

img

二.安装禅道

1.解压禅道的压缩包

将安装包直接解压到/opt目录下

特别说明:不要 解压到别的⽬录再拷⻉到/opt/,因为这样会导致⽂件的所有者和读写权限改变, 也不要解压后把整个⽬录777权限 。

命令:

sudo tar -zxvf ZenTaoPMS.18.3.zbox_64.tar.gz -C /opt

2.启动禅道

执行/opt/zbox/zbox start命令开启Apache和Mysql。
执⾏/opt/zbox/zbox stop命令停⽌Apache和Mysql。
执⾏/opt/zbox/zbox restart命令重启Apache和Mysql。

3.访问禅道

启动 Apache和Mysql服务后,
浏览器直接访问 http://禅道服务器ip:apache端⼝ 即可访问和登录禅道。
注:如果⽹⻚⽆法访问,请先关闭禅道所在电脑的防⽕墙和selinux再刷新⽹⻚访问试⼀下。(使⽤云服务器请注意在安全组中开放apache使⽤端⼝)
禅道默认管理员帐号是 admin,密码 123456。

4.查看服务器IP的方法

img

5.浏览器直接访问即可

img

三.遇到的问题

img

大概率是因为禅道所在电脑的防⽕墙和selinux未关闭

首先查看防火墙的状态

systemctl status firewalld

img

关闭防火墙

systemctl stop firewalld

再次查看防火墙状态(已关闭)

img

最好把防火墙开机自启也关闭,避免不必要的麻烦

systemctl disable firewalld.service

之后再关闭selinux(可临时关闭也可以永久性关闭)

首先可以查看一下状态(注意看Current mode的状态)

/usr/sbin/sestatus

关闭前Current mode的状态为 enforcing

这里选择了永久性关闭

vim /etc/sysconfig/selinux

selinux=enforcing 改为 selinux=disabled

img

再次查看状态(请记得重启reboot)

/usr/sbin/sestatus

最后,再次通过浏览器访问禅道!!!

img

成功!!!

大数据组件

Hbase

1、拉取hbase镜像

# 查找镜像
docker search hbase# 拉取镜像
docker pull harisekhon/hbase:latest

图片alt

图片alt

2、创建容器

# 未指定主机名
docker run -d --name hbase -p 2181:2181 -p 16010:16010 -p 16020:16020 -p 16030:16030 harisekhon/hbase:latest# 指定主机名
docker run -d -h hbase \
-p 2181:2181 -p 8080:8080 -p 8085:8085 -p 9090:9090 \
-p 9095:9095 -p 16000:16000 -p 16010:16010 -p 16020:16020 \
-p 16201:16201 -p 16301:16301 \
--name hbase harisekhon/hbase:latest

这里注意一点,对于端口映射,hbase用到了很多端口,有的地方直接使用-P参数,而不是用-p做端口一一映射。
同时,-h选项中的参数hbase名字不要修改,否则会连不上节点。

docker run -d --name hbase -P harisekhon/hbase

如果通过-P参数,会将容器内部所有监听的端口都映射为随机端口,我们可以看看容器状态:

图片alt

其中,16010端口是hbase提供的webui界面暴露的端口,映射为了32770,我们可以通过虚拟机地址,以及这个端口访问hbase webui。

hbase webui的地址如下:

http://192.168.1.113:16010/master-status

图片alt

到了这里,通过web界面能够看到hbase状态,然后,可以进入容器,运行hbase shell,执行建表,添加数据,扫描数据都没有问题。但是如果外部程序,比如java需要操作hbase,就非常麻烦。

所以,这里不建议直接使用-P(大写)的方式启动hbase。

推荐的启动方式:

docker run -d –name hbase -p 2181:2181 -p 16010:16010 -p 16020:16020 -p 16030:16030 harisekhon/hbase

不推荐的启动方式

docker run -d --name -P harisekhon/hbase

3、测试容器

# 进入容器
docker exec -it hbase /bin/bash# 启动shell
hbase shell# 查看表名列表
list# 创建表
# 语法:create <table>, {NAME => <family>, VERSIONS => <VERSIONS>}
create 'userinfo',{NAME => 'user', VERSIONS => 2},{NAME => 'score', VERSIONS => 2}

图片alt

Clickhouse

项目常用组件

Hutool

常用工具类

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.2</version>
</dependency>

EasyExcel

excel文件导入导出

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.0</version>
</dependency>

Knife4j

接口文档

<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version>
</dependency>

Elasticsearch

搜索引擎

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.6.2</version>
</dependency>

Fastjson

json解析

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version>
</dependency>

Aspectj

Aop切面

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId>
</dependency>

Admin-server

服务端监控

<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.6.6</version>
</dependency>

相关配置

server:port: 6091
spring:application:name: rms-monitorboot:admin:monitor:default-timeout: 30000ui:title: RMS监控中心server:enabled: true

Admin-client

客户端监控

<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.6.6</version>
</dependency>

相关配置

server:port: 6080
spring:application:name: rms-risk-serviceservlet:multipart:max-file-size: 10MBmax-request-size: 20MBmvc:path-match:matching-strategy: ant_path_matcherboot:admin:monitor:default-timeout: 30000client:
#        enabled: trueurl: http://192.168.1.51:6091instance:service-url: http://192.168.1.51:6091

Actuator

健康检查

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Security

权限管理

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

相关配置

Mysql

数据库

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version><scope>runtime</scope>
</dependency>

相关配置

  datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.1.101:3306/rms-system?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: Rlyy#234

Mybatis-Plus

数据持久化

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version>
</dependency>

相关配置

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.rlcould.system.entity

Lombok

实体代码注解组件

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

Jwt

token组件

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.0.0</version>
</dependency>

相关代码

package com.xxx.system.util;import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.rlcloud.common.utils.JwtTokenThreadLocal;
import com.rlcloud.system.entity.User;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** @version v1.0 创建时间:11:35* @author: 作者:xxx* @description 描述:auth0.jwt工具类*/
public class JwtHelper {//一般token过期时间30分钟或者1个小时private static long TOKEN_EXPIRE = 1000*60*30;  //30分钟,单位为毫秒private static String salt = "xxxxxx";        //秘钥//1. 创建tokenpublic static String createToken(Map<String,Object> maps){//设置过期时间Date expiresAt = new Date(System.currentTimeMillis() + TOKEN_EXPIRE);Algorithm alg = Algorithm.HMAC256(salt);    //秘钥进行加密,类似md5JWTCreator.Builder builder = JWT.create();for(String key : maps.keySet()){builder.withClaim(key, String.valueOf(maps.get(key)));}String token = builder.withExpiresAt(expiresAt).sign(alg);return token;}//2. 解析tokenpublic static String decode(String token, String who){if(StrUtil.isBlank(token)){throw new RuntimeException("非法用户,请登录");}return JWT.decode(token).getClaim(who).asString();}public static String getUserId(){return decode(JwtTokenThreadLocal.get(), JwtUserEnum.userId.name());}public static Integer getTenantId(){return Integer.valueOf(decode(JwtTokenThreadLocal.get(), JwtUserEnum.tenantId.name()));}//获取当前用户信息public static User getUser(){String token = JwtTokenThreadLocal.get();User curUser = new User();curUser.setTenantId(Integer.valueOf(decode(token, JwtUserEnum.tenantId.name())));curUser.setId(Long.valueOf(decode(token, JwtUserEnum.userId.name())));curUser.setName(decode(token, JwtUserEnum.userName.name()));curUser.setDeptId(decode(token, JwtUserEnum.deptId.name()));curUser.setDeptName(decode(token, JwtUserEnum.deptName.name()));curUser.setSuperLevel(Integer.valueOf(decode(token, JwtUserEnum.supperLevel.name())));return curUser;}//3. 校验token是否过期public static boolean verify(String token){//跟当前时间进行比较,如果超过当前时间返回true(过期),如果没有超过返回false(未过期)。return !JWT.decode(token).getExpiresAt().after(new Date());}public static void main(String[] args) {Map<String, Object> maps = new HashMap<>();maps.put(JwtUserEnum.userId.name(), "1");maps.put(JwtUserEnum.userName.name(), "tony");maps.put(JwtUserEnum.deptId.name(), "2");maps.put(JwtUserEnum.deptName.name(), "网易");maps.put("supperLevel", 9);String t = JwtHelper.createToken(maps);System.out.println(t);String userId = JwtHelper.decode(t, JwtUserEnum.userId.name());System.out.println(userId);String name = JwtHelper.decode(t, JwtUserEnum.userName.name());System.out.println(name);String supperLevel = JwtHelper.decode(t, "supperLevel");System.out.println(supperLevel);try {Thread.sleep(3000); //睡眠3秒}catch (Exception e){}System.out.println(JwtHelper.verify(t));}
}

枚举类

package com.rlcloud.system.util;/*** @version v1.0 创建时间:2023/11/20 15:59* @author: 作者:xxx* @description 描述:用于User信息获取,规定下面值*/
public enum JwtUserEnum {tenantId("tenant", 0),userId("userId",1),userName("userName",2),deptId("deptId",3),deptName("deptName",4),supperLevel("supperLevel",5);JwtUserEnum(String who, int i) {}
}

Logstash-logback

集成Logstash

<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>5.3</version>
</dependency>

配置文件:logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration><include resource="org/springframework/boot/logging/logback/defaults.xml"/><include resource="org/springframework/boot/logging/logback/console-appender.xml"/><!--应用名称--><property name="SERVER_NAME" value="rms-risk-service"/><!--日志文件保存路径--><property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/><contextName>${APP_NAME}</contextName><!--每天记录日志到文件appender--><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern><maxHistory>30</maxHistory></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder></appender><!--输出到logstash的appender--><appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"><!--可以访问的logstash日志收集端口--><destination>192.168.1.55:4560</destination><encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/></appender><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/><appender-ref ref="LOGSTASH"/></root>
</configuration>

Nacos

微服务配置与注册

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.5.RELEASE</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.5.RELEASE</version>
</dependency>

Redis

缓存存储

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.2.8.RELEASE</version>
</dependency>

Redisson

分布式锁

<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>2.2.8.RELEASE</version>
</dependency>

Spring-boot-mail

发邮件

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

相关代码

package com.rlcloud.mail.config;import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.rlcloud.mail.service.KingliMailSender;@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class MailConfig {@Beanpublic KingliMailSender initMailSender() {return new KingliMailSender(); }}
package com.rlcloud.mail.config;import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;import lombok.Data;@Data
@Configuration
@ConfigurationProperties(prefix="spring.mail")
public class MailProperties {private String host;private String username;private String password;private Integer port;private String protocol = "smtp";private Charset defaultEncoding;private Map<String, String> properties = new HashMap<>();}
package com.rlcloud.mail.constant;public interface MailConstant {public static final String CONFIG_ERROR 				= "未配置邮件服务!";public static final String SEND_ERROR 					= "邮件发送失败!";public static final String PARAM_ERROR					= "参数错误!";public static final String SUCCESS 						= "发送成功!";}
package com.rlcloud.mail.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.util.StringUtils;
import com.rlcloud.mail.config.MailProperties;
import com.rlcloud.mail.constant.MailConstant;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class KingliMailSender {@AutowiredMailProperties mailProperties;@AutowiredJavaMailSenderImpl javaMailSender;public String simpleSend(String subject, String[] to, String[] cc, String[] bcc, String content) {if (!check()) {return MailConstant.CONFIG_ERROR;}SimpleMailMessage simple = new SimpleMailMessage();simple.setSubject(subject);simple.setTo(to);simple.setFrom(mailProperties.getUsername());if (cc != null && cc.length > 0) {simple.setCc(cc);}if (bcc != null && bcc.length > 0) {simple.setBcc(bcc);}simple.setText(content);try {javaMailSender.send(simple);log.debug(String.format("邮件发送成功!【%s】To: %s", subject, to));} catch (MailException e) {e.printStackTrace();log.error("发送邮件失败!" + e.getMessage());return MailConstant.SEND_ERROR + e.getMessage();}return MailConstant.SUCCESS;}public String simpleSend(String subject, String to, String cc, String bcc, String content) {String[] toArray = to != null ? to.split(",") : null;String[] ccArray = cc != null ? cc.split(",") : null;String[] bccArray = bcc != null ? bcc.split(",") : null;return simpleSend(subject, toArray, ccArray, bccArray, content);}public String simpleSend(SimpleMailMessage smm) {if (!check()) {return MailConstant.CONFIG_ERROR;}if (smm == null) {return MailConstant.PARAM_ERROR + "不能发送空消息!";}try {smm.setFrom(mailProperties.getUsername());javaMailSender.send(smm);log.debug(String.format("邮件发送成功!【%s】To: %s", smm.getSubject(), smm.getTo()));} catch (MailException e) {e.printStackTrace();log.error("发送邮件失败!" + e.getMessage());return MailConstant.SEND_ERROR + e.getMessage();}return MailConstant.SUCCESS;}private boolean check() {if (StringUtils.isEmpty(javaMailSender.getHost())) {return false;}if (StringUtils.isEmpty(javaMailSender.getUsername())) {return false;}if (StringUtils.isEmpty(javaMailSender.getPassword())) {return false;}return true;}
}

xxl-job

官网地址:https://www.xuxueli.com/xxl-job/

https://gitee.com/xuxueli0323/xxl-job

Poi-tl Word 模板引擎

<!-- Poi-tl Word 模板引擎-->
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.9.1</version>
</dependency>

Arthas

官网地址:https://arthas.aliyun.com/doc/download.html

curl -O https://arthas.aliyun.com/arthas-boot.jar

1、项目集成Skywalking
2、Elk安装资料整理
3、Skywalking软件安装整理
4、系统集成Gateway、nacos
5、集成Sonarqube

Prometheus

maven依赖:

<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

配置文件:prometheus.yml

# my global config
global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:- alertmanager:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["192.168.1.56:9090"]
#  - job_name: 'mysql'
#    static_configs:
#      - targets: ['192.168.1.101:3306']- job_name: 'nacos'# metrics_path defaults to '/metrics'# scheme defaults to 'http'.metrics_path: '/nacos/actuator/prometheus'static_configs:- targets: ['192.168.1.111:8848']#  # 新添加的采集目标elasticsearch服务
#  - job_name: "elasticsearch"
#    static_configs:
#      - targets: ["192.168.1.55:9200"]
#      
#  # 新添加的采集目标web前端服务
#  - job_name: "rms-web"
#    static_configs:
#      - targets: ["192.168.1.2:3110"]
#
#  # 新添加的采集目标web前端服务
#  - job_name: "skywalking"
#    static_configs:
#      - targets: ["192.168.1.52:8686"]

文件转换

Markdown文件转换成Word文档

项目框架使用

Mysql转MarkDown文件

package com.rlcloud.risk.util;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** Mysql转MarkDown文件*/
public class Mysql2Markdown {public static void main(String[] args) {System.out.println("请输入文件路径,例如:d:\\outsourcing.sql");Scanner sc = new Scanner(System.in);String input = sc.nextLine();String path = "D:\\outsourcing.sql";  //文件路径File file = new File(path);StringBuffer sbf = new StringBuffer();BufferedReader reader = null;StringBuffer table_name_buff = new StringBuffer();String tableString;int tablenum = 0;FileWriter fileWriter = null;//把sql文件按照空行分段,每一段存到map1中,num表示有多少段int num = 0;Map<String, String> sql_section_map = new HashMap<String,String>();Map<String, String> table_section_map = new HashMap<String,String>();    //存储表片段Map<String, String> table_name_map = new HashMap<String,String>();    //存储表名Map<String, String> table_description_map = new HashMap<String,String>();	//存储表描述Map<String, String> row_name_map = new HashMap<String,String>();	//存储表列名Map<String, String> map_row_type = new HashMap<String,String>();	//存储列类型Map<String, String> map_row_description = new HashMap<String,String>();	//存储列描述try {reader = new BufferedReader(new FileReader(file));String tempStr;while ((tempStr = reader.readLine()) != null) {sbf.append(tempStr+"\n");if(tempStr.equals("")){sql_section_map.put("duan"+num, sbf.toString());sbf.setLength(0);num++;}}reader.close();String aaString = sbf.toString();		//读取sql文件后转为字符串String table_name_regex = "CREATE TABLE `(\\S*)`";   //匹配表名String table_description_regex = "COMMENT='([\u4e00-\u9fa5_a-zA-Z0-9\\S]*)';";   //匹配表描述String regex_row_description = "COMMENT '([\u4e00-\u9fa5_a-zA-Z0-9\\S]*)',";	//匹配列描述String table_row_name_regex = "  `(\\S*)`";   //匹配字段String regex_type = "  `(\\S*)` (\\S*)";   //匹配字段类型// 创建 Pattern 对象Pattern table_name_Pattern = Pattern.compile(table_name_regex);Pattern table_description_Pattern = Pattern.compile(table_description_regex);Pattern table_row_name_Pattern = Pattern.compile(table_row_name_regex);Pattern pattern_row_type = Pattern.compile(regex_type);Pattern pattern_row_description = Pattern.compile(regex_row_description);// 现在创建 matcher 对象for (int i = 0; i < num; i++) {tableString = sql_section_map.get("duan"+i);Matcher m1 = table_name_Pattern.matcher(tableString);if(m1.find()){int a = m1.start(1);//m1.find(a);  //find(int start)  //有参函数表示  重新设置该匹配器,然后尝试从指定的索引开始找,start:索引。table_name_buff.append(m1.group(1)+",");table_section_map.put("table"+tablenum, sql_section_map.get("duan"+i));tablenum++;}else{sql_section_map.remove("duan"+i);}}/**************************************段处理完成,下面根据获取的表的数量进行解析************************************************/String [] table_name_array = table_name_buff.toString().split(","); //表名for (int i = 0; i < table_name_array.length; i++) {table_name_map.put("table"+i, table_name_array[i]);}/*** 每一行分开,匹配列名*/String aa = "";String bb = "";String cc = "";for (int i = 0; i < table_section_map.size(); i++) {String[] aStrings = table_section_map.get("table"+i).split("\n");Matcher m2 = table_description_Pattern.matcher(table_section_map.get("table"+i));if (m2.find()) {table_description_map.put("table"+i, m2.group(1));//System.out.println("table"+i+":"+table_description_map.get("table"+i));}for (int j = 0; j < aStrings.length; j++) {Matcher m3 = table_row_name_Pattern.matcher(aStrings[j]);Matcher m4 = pattern_row_type.matcher(aStrings[j]);Matcher m5 = pattern_row_description.matcher(aStrings[j]);//System.out.println(m3.groupCount());while(m3.find()){aa +=m3.group(1)+",";}while(m4.find()){bb +=m4.group(2)+",";if(m5.find()){cc +=m5.group(1)+",";}else {cc += "null"+",";}}}row_name_map.put("table"+i, aa);map_row_type.put("table"+i, bb);map_row_description.put("table"+i, cc);aa = "";bb = "";cc = "";}//组织输出md文件内容String text = "# 数据库文档\n\n";text += "## 数据表列表\n\n";String table_desstr = "";   //表描述for (int i = 0; i < table_section_map.size(); i++) {table_desstr = table_description_map.get("table"+i);String tablenamestr = table_name_map.get("table"+i);if (table_desstr != null) {text += "## 表名:"+tablenamestr+"("+table_description_map.get("table"+i)+")\n\n";}else {text += "## 表名:"+tablenamestr+"\n\n";}//text += "## 表名:"+tablenamestr+"("+table_description_map.get("table"+i)+")\n\n";text += "字段名|数据类型|字段描述\n";text += ":---:|:---:|:---:\n";String[] rownames = row_name_map.get("table"+i).split(",");String[] rowtypes = map_row_type.get("table"+i).split(",");String[] rowdes = map_row_description.get("table"+i).split(",");try {for (int j = 0; j < rownames.length; j++) {if(rowdes[j].equals("null")){rowdes[j]="";}text += rownames[j]+"|"+rowtypes[j]+"|"+rowdes[j]+"\n";}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("字段类型与字段描述匹配出错,请查看匹配规则与sql文件内容是否相符,\n测试过程中发现,自动导出的sql文件有可能出现字段名字后出现两个空格,匹配规则为1个空格");}//System.out.println(text);}System.out.println("表描述"+table_description_map);//文件输出fileWriter =  new FileWriter("d:\\外包管理系统数据库设计文档.md",false);fileWriter.write(text);fileWriter.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

返回时间json格式问题

@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")

例如:

/**
* 子任务评估开始事件
*/
@ApiModelProperty(value = " 子任务评估开始事件")
@ExcelProperty(" 子任务评估开始事件")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
private Date startTime;

Mybatis-plus in多个值(逗号)查询

 QueryWrapper<RiskPool> qw = new QueryWrapper<>();
if(StrUtil.isNotEmpty(riskPool)){qw.lambda().in(RiskPool::getId, riskPool.split(","));
}

Springboot解决Long /BigInteger /BigDecimal类型数据传给前端损失精度问题

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;import java.math.BigDecimal;
import java.math.BigInteger;/*** 参数返回到前端,将Long /BigInteger /BigDecimal转换成String* @author xrj* @date 2020/5/13*/
@Configuration
public class WebMvcAutoConfiguration {/*** 初始化对象* @param builder*/@Bean@Primarypublic ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {final JavaTimeModule simpleModule = new JavaTimeModule();//序列化将Long转String类型simpleModule.addSerializer(Long.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);SimpleModule bigIntegerModule = new SimpleModule();//序列化将BigInteger转String类型bigIntegerModule.addSerializer(BigInteger.class, ToStringSerializer.instance);SimpleModule bigDecimalModule = new SimpleModule();//序列化将BigDecimal转String类型bigDecimalModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);return builder.createXmlMapper(false).modulesToInstall(simpleModule).build();}
}

Mybatis-Plus通过全局拦截实现查询SQL根据创建时间排序(create_time)

①自定义SQL拦截器(通过重写processSelect方法,对select进行拦截,并构建添加规则)

/*** 自定义SQL拦截器* @author xsong*/
@Slf4j
@Component
public class CustomSQLInterceptor extends JsqlParserSupport implements InnerInterceptor {@Overridepublic void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {// 这里固定这么写就可以了PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);MappedStatement ms = mpSh.mappedStatement();if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) {return;}PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();mpBs.sql(parserMulti(mpBs.sql(), null));}/*** 查询操作拦截* 该方法由JsqlParserSupport提供,主要用于通过API的方式操作SQL* 思路:通过API构建出新的条件,并将新的条件和之前的条件拼接在一起*/@Overrideprotected void processSelect(Select select, int index, String sql, Object obj) {// 解析SQLPlainSelect plainSelect = (PlainSelect) select.getSelectBody();// 构建排序规则OrderByElement orderByElement = new OrderByElement();// 设置为从大到小(降序)orderByElement.setAsc(false);// 设置排序字段orderByElement.setExpression(new Column("create_time"));// 重新封装条件plainSelect.addOrderByElements(orderByElement);// System.out.println(plainSelect);}/*** 插入操作拦截*/@Overrideprotected void processInsert(Insert insert, int index, String sql, Object obj) {}/*** 更新操作拦截*/@Overrideprotected void processUpdate(Update update, int index, String sql, Object obj) {}/*** 删除操作拦截*/@Overrideprotected void processDelete(Delete delete, int index, String sql, Object obj) {}
}

②将自定义SQL拦截器添加到MybatisPlus拦截器中

/*** MyBatisPlus配置类* @author xsong*/
@Configuration
public class MyBatisPlusConfig {/*** MybatisPlus拦截器*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 分页插件拦截器interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 自定义SQL拦截器interceptor.addInnerInterceptor(new CustomSQLInterceptor());return interceptor;}
}

③实现效果

在这里插入图片描述

List转字符串 a,b,c

String riskDomainList = String.join(",", riskDomainIds);
String secondRiskDomainList = String.join(",", secondRiskDomainIds);

Java中将List列表转换为字符串的三种方法

如何在 Java中将List 转换为 String。接下来使用Java 8 Streams Collectors apiString.join()方法将带有逗号分隔符或自定义分隔符的集合转换为字符串。这种转换是通过使用 java api 方法的简单步骤完成的。首先了解如何使用toString()方法将 List 转换为 String,最后学习著名的 apache 库命令StringUtils.join()方法。

对于所有示例,输入列表必须是 String 作为List类型,否则我们需要将非字符串转换为 String。例如,List 是 Double 类型,然后需要先将 double 转换为字符串。

使用标准 toString() 方法

List.toString()是最简单的,但它在开头和结尾添加方括号,每个字符串用逗号分隔符分隔。
缺点是我们不能用另一个分隔符替换逗号,也不能去掉方括号。

import java.util.Arrays;
import java.util.List;public class ListToStringUsingToStringExample {public static void main(String args) {// creating a list with strings.List<String> list = Arrays.asList("One", "Two", "Three", "Four", "Five");// converting List<String> to String using toString() methodString stringFromList = list.toString();// priting the stringSystem.out.println("String : "+stringFromList);}
}输出:
String : [One, Two, Three, Four, Five]

Java 8 String.join()

java 8 String添加了一个特殊的方法String.join()以将集合转换为具有给定分隔符的字符串。

public class ListToStringUsingString_JoinExample {public static void main(String args) {// creating a list with strings.List<String> list = Arrays.asList("One", "Two", "Three", "Four", "Five");// converting List<String> to String using toString() methodString stringFromList = String.join("~", list);// priting the stringSystem.out.println("String with tilde delimiter: "+stringFromList);// delimiting with pipe | symbol.String stringPipe = String.join("|", list);// printingSystem.out.println("String with pipe delimiter : "+stringPipe);}
}输出:
String with tilde delimiter: One~Two~Three~Four~Five
String with pipe delimiter : One|Two|Three|Four|Five

Collectors.joining()

Collectors.join()方法来自 java 8 stream api。Collctors.joining()方法将分隔符、前缀和后缀作为参数。此方法将列表转换为具有给定分隔符、前缀和后缀的字符串。
查看以下有关使用不同分隔符的 join() 方法的示例。但是,String.join() 方法不提供前缀和后缀选项。
如果您需要自定义分隔符、前缀和后缀,请使用这些。如果您不想要前缀和后缀,则提供空字符串以不在结果字符串前后添加任何内容。

public class ListToStringUsingString_JoinExample {public static void main(String args) {// creating a list with strings.List<String> list = Arrays.asList("One", "Two", "Three", "Four", "Five");// using java 8 Collectors.joining with delimiter, prefix and suffixString joiningString = list.stream().collect(Collectors.joining("-", "{", "}"));// printingSystem.out.println("Collectors.joining string : "+joiningString);String joiningString3 = list.stream().collect(Collectors.joining("@", "", ""));// printingSystem.out.println("Collectors.joining string with @ separator : "+joiningString3);}
}输出:
Collectors.joining string : {One-Two-Three-Four-Five}
Collectors.joining string with @ separator : One@Two@Three@Four@Five

Apache Commons StringUtils.join()

最后的方法是使用来自 apache commons 包的外部库。该库有一个方法StringUtils.join() ,它采用类似于 String.join() 方法的列表和分隔符。

public class ListToStringUsingStringUtils_JoinExample {public static void main(String args) {// creating a list with strings.List<String> list = Arrays.asList("One", "Two", "Three", "Four", "Five");// using java 8 Collectors.joining with delimiter, prefix and suffixString joiningString = StringUtils.join(list, "^");// printingSystem.out.println("StringUtils.join string with ^ delimiter : "+joiningString);String joiningString3 = StringUtils.join(list, "$");// printingSystem.out.println("StringUtils.join string with @ separator : "+joiningString3);}
}输出:
StringUtils.join string with ^ delimiter : One^Two^Three^Four^Five
StringUtils.join string with @ separator : One$Two$Three$Four$Five

结论

在本文中,我们已经看到了在 java 8 之前和之后如何使用不同的方法在 java 中将 List 转换为 String。对给定的分隔符使用 String.join() 方法从 List 生成字符串是很好的。或者,如果您想添加前缀或后缀,请使用带有分隔符、前缀和后缀值的流 api Collectors.joining() 方法。

Linux 检查java服务宕机

要在 Linux 上检查 Java 服务的状态并确定其是否已经停止运行,可以使用以下命令来完成:

  1. 首先,打开终端或 SSH 连接到目标 Linux 系统。

  2. 输入以下命令来检查正在运行的进程列表中是否存在与 Java 相关的进程:

    ps -ef | grep java
    

    如果有任何包含 “java” 字样的进程显示在结果中,则说明 Java 服务仍然在运行。

  3. 若要获取更详细的信息,可以使用 jps 命令(Java Virtual Machine Process Status Tool)来列出所有正在运行的 Java 进程及其对应的进程 ID (PID):

    jps -l
    

  4. 此外,还可以通过检查特定的日志文件来判断 Java 服务是否异常退出。根据不同的配置和部署情况,日志文件位于 /var/log//opt/logs/ 等路径下。可以使用以下命令来查看最新的日志内容:

    tail -n <number_of_lines> /path/to/your/logfile.log
    

    <number_of_lines> 替换为想要查看的日志行数,/path/to/your/logfile.log 替换为实际的日志文件路径。

  5. 如果需要重新启动 Java 服务,可以使用类似以下的命令:

    sudo service your-service restart
    

    这里的 your-service 应该被替换为实际的 Java 服务名称。

  6. 如果希望自动化地执行上述操作,可以编写 Shell 脚本来处理。以下是一个简单的示例:

    #!/bin/bash# Check if any Java process is running
    if pgrep -x "java" > /dev/null; thenecho "Java processes are still running."
    elseecho "No Java processes found."
    fi# Restart the Java service using systemctl command
    sudo systemctl restart your-service
    

    注意修改脚本中的 your-service 为实际的 Java 服务名称。保存脚本后,添加执行权限并运行它。

Linux监控Springboot服务宕机,自动重启脚本:

# An highlighted block
#!/bin/bash# 设置变量,指向 jar 包的位置
jar_path=/mnt/chonggou/rms-basic-service.jar# 定义一个函数来检查程序是否宕机
check_status() {# 使用 ps 命令检查 jar 包是否在运行running=$(ps -ef | grep $jar_path | grep -v grep)if [ -z "$running" ]; thenreturn 1elsereturn 0fi
}# 循环检查程序是否宕机
while true; docheck_statusif [ $? -eq 1 ]; thenecho "rms-basic-Service is down, restarting..."# 如果宕机了,则启动 jar 包#nohup java -jar $jar_path &nohup java -javaagent:/mnt/skywalking-agent/skywalking-agent-basic/skywalking-agent.jar -DSW_AGENT_NAME=dev::rms-basic-service -Dskywalking.collector.backend_service=192.168.1.52:11800 -jar $jar_path &fisleep 10
done

List与String互相转换,并以“,”分割

String转List

String nameArr = "张三, 李四, 王五";
List<String> alName = Arrays.asList(nameArr .split(","));

List转String

List<String> alName = Arrays.asList("张三, 李四, 王五");
String nameArr = alName.stream().collect(Collectors.joining(","));

Mybatis-plus in用法

 //根据主任务id查询风险问题List<RiskAssessmentResult> riskAssessmentResultList = new ArrayList<RiskAssessmentResult>();List<String> riskLevel = Stream.of("中","高").collect(Collectors.toList());QueryWrapper qw = new QueryWrapper();qw.eq("main_task_id",riskAssessmentTaskEntity.getId());qw.in(!CollectionUtils.isEmpty(riskLevel),"risk_level",riskLevel);List<RiskPoolSubtaskRel> riskPoolSubtaskRelList = riskPoolSubtaskRelService.list(qw);

Windows 常用命令

查看端口号

netstat -ano | findstr :8080

涨知识

Argo

开源组件文档地址

开源组件名称地址来源
Easy Excelhttps://easyexcel.opensource.alibaba.com/阿里巴巴
RunnerGohttps://wiki.runnergo.cn/docs/42
EasyPoihttp://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8http://doc.wupaas.com/docs/easypoi
夜莺(Nightingale)v5.9 使用手册https://www.bookstack.cn/books/nightingale-5.9-zh

软件下载

软件名称地址来源
SonarQubehttps://www.sonarsource.com/products/sonarqube/downloads/官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2803289.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Web Serial API串口通信,实现web和electron扫码枪读取数据

文章目录 前言一、Serial API是什么&#xff1f;二、API使用步骤1.navigator.serial.requestPort()2.port.open(options)3.reader.read()4.port.close()其他常见API:完整代码 三、electron使用 前言 本文将讲述Web Serial API简单应用&#xff0c;以扫码枪为示例&#xff0c;通…

idea查找所有未使用的代码

1.背景 最近在做无用代码下线的时候发现一个方法里会引用很多个方法&#xff0c;一旦该方法删除以后&#xff0c;里面被引用的方法应该也一同下线&#xff0c;但是一个一个的找过去比较耗费精力&#xff0c;下面给大家推荐一个idea自带的代码分析工具 2.代码分析工具 Code-&…

【无标题】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘

项目场景&#xff1a; 做单链表反转题目&#xff0c;报错&#xff1a;member access within null pointer of type ‘struct ListNode’ 题目链接:LINK 问题描述 我明明在初始化指针时候&#xff0c;已经处理了n2->next情况却依然报错 这个报错提示含义是&#xff1a;大概就…

创新性3D数据合成模型,微软推出EgoGen

随着AR、VR等设备的广泛应用,第一人称的应用开始增多。但在研发方面面临不同的挑战,例如&#xff0c;图像模糊、视觉混乱、遮挡更严重等&#xff0c;给视觉模型的训练带来重大挑战。 一方面,人工标注真实第一视角数据集&#xff0c;来培训深度学习模型的成本和难度都很高。另一…

第八章 shell编程之sed

目录 1.1. 概念 1.1.1. 工作原理&#xff1a; 1.2. 基本语法 1.2.1. 格式 1.2.2. 参数 1.2.3. 定址符 1.2.4. 操作 1.3. 输出文本 1.3.1. 范例文件&#xff1a; 1.3.2. 示例 1.4. 文本替换 1.4.1. 范例文件 1.4.2. 格式&#xff1a; 1.4.3. 示例 1.5. 删除文本 …

提升生产能力的必备工具——MES系统自动排产

在现代制造业中&#xff0c;生产能力的提升对企业发展至关重要。随着市场竞争的日益激烈&#xff0c;企业不仅需要提高产品质量&#xff0c;还需要提高生产效率。而MES系统自动排产作为一种先进的生产管理工具&#xff0c;可以帮助企业高效地安排生产&#xff0c;实现生产能力的…

江科大stm32学习笔记——【3-2】GPIO输出:LED闪烁LED流水灯蜂鸣器

&#xff08;一&#xff09; 硬件连接 1.LED闪烁 LED灯正极连接面包板电源正极&#xff0c;LED负极连接单片机A0口 (也可以LED负极连面包板负极&#xff0c;LED正极连接单片机A0口) 跳线连接单片机3.3和面包板正极&#xff0c;连接单片机GND和面包板负极 2.LED流水灯 3.蜂鸣…

你并不了解 JavaScript:入门 - 第二版 - 第二章:JS 概观

第二章&#xff1a;JS 概观 学习 JS 的最好方法就是开始写 JS。 要做到这一点&#xff0c;你需要知道这门语言是如何工作的&#xff0c;而这正是我们在这里要重点讨论的。即使你以前用过其他语言编程&#xff0c;也要慢慢适应 JS&#xff0c;并确保练习每一块。 这一章并不是…

自学黑客的这些坑千万别踩,不然就是在做无用功!

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且实际向安全过渡后可用到的关键知识并不多 一般人如果想要把编程学好再开始学习网络安全往…

并发编程(3)JMM

5 共享模型之内存 本章内容 上一章讲解的 Monitor 主要关注的是访问共享变量时&#xff0c;保证临界区代码的原子性. 这一章我们进一步深入学习共享变量在多线程间的【可见性】问题与多条指令执行时的【有序性】问题 5.1 Java 内存模型 JMM 即 Java Memory Model&#xff…

SQL库操作

1、创建数据库 概念 创建数据库&#xff1a;根据项目需求创建一个存储数据的仓库 使用create database 数据库名字创建 数据库层面可以指定字符集:charset/character set 数据库层面可以指定校对集:collate 创建数据库会在磁盘指定存放处产生一个文件夹 创建语法 create …

六.生成makefile文件 并基于makefile文件编译opencv

1.点击【Generate】 生成makefile文件 2.进入目录下编译opencv源码&#xff0c;mingw32-make -j 8 3..编译出现报错 4.取消[WITH_OPENCL_D3D11_NV]选项&#xff0c;再次【configure】【generate】 然后再次编译&#xff1a;mingw32-make -j 8

【springblade】springblade(bladeX) 数据权限失效原因分析

文章目录 数据权限接口权限 前言&#xff1a;最近博主在按照bladeX官方文档 配置数据权限 结果发现失效了&#xff0c;网上搜了一下没找到合适的答案&#xff0c;本着求人不如求己的精神&#xff0c;自己调试了一下发现了问题所在&#xff0c;也大致看了一下bladeX的权限逻辑。…

这份攻略帮助你分分钟构建出“幻兽帕鲁游戏”极致体验【下】

在上一篇文章这份攻略帮助你分分钟构建出“幻兽帕鲁游戏”极致体验【上】中写了&#xff0c;极狐GitLab 将 terraform state 文件管理了起来。这篇文章将演示如何将所有的 terraform 文件存储到极狐GitLab 中&#xff0c;并且使用 CI/CD 自动实现 terraform 命令的执行。 在 D…

最简单方式把jar打包成Windows服务

废话 &#x1f622; 将JAR文件转化为Windows服务是一种高效且常见的Java应用部署策略。这种转变赋予了Java应用程序在Windows操作系统上以无界面后台服务模式运行的能力&#xff0c;从而实现了持续、稳定且可靠的功能提供。这种部署方式不仅提升了应用的可用性&#xff0c…

re-迷宫题学习

re中的迷宫问题有以下特点: 在内存中布置一张 "地图"将用户输入限制在少数几个字符范围内.一般只有一个迷宫入口和一个迷宫出口 布置的地图可以由可显字符 (比如#和*)组合而成 (这非常明显, 查看字符串基本就知道这是个迷宫题了.), 也可以单纯用不可显的十六进制值进…

【鸿蒙 HarmonyOS 4.0】UIAbility、页面及组件的生命周期

一、背景 主要梳理下鸿蒙系统开发中常用的生命周期 二、UIAbility组件 UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。 UIAbility组件是系统调度的基本单元&#xff0c;为应用提供绘制界面的窗口&#xff1b;一个UIAbility组件中可以通过多个页…

【大厂AI课学习笔记NO.50】2.3深度学习开发任务实例(3)任务背景与目标

我们经常在做项目的时候&#xff0c;觉得分析背景和目标是浪费时间&#xff0c;觉得不过如此。 其实目标梳理特别重要&#xff0c;直接决定你数据的需求分析&#xff0c;模型的选择&#xff0c;决定你交付的质量。 人工智能项目也和其他项目一样&#xff0c;不要想当然&#…

7-liunx服务器规范

目录 概况liunx日志liunx系统日志syslog函数openlog 可以改变syslog默认输出方式 &#xff0c;进一步结构化 用户信息进程间的关系会话ps命令查看进程关系 系统资源限制改变工作目录和根目录服务器程序后台话 概况 liunx服务器上有很多细节需要注意 &#xff0c;这些细节很重要…

Redis进阶篇

Redis线程模型 redis是基于内存运行的高性能k-v数据库&#xff0c;6.x之前是单线程, 对外提供的键值存储服务的主要流程 是单线程&#xff0c;也就是网络 IO 和数据读写是由单个线程来完成&#xff0c;6.x之后引入多线程而键值对读写命 令仍然是单线程处理的&#xff0c;所以 …