likes
comments
collection
share

常用操作合集五

作者站长头像
站长
· 阅读数 10

写在前面

在工作中,我们可能会遇到一些问题,然后通过自己得一顿操作,最终把问题解决了。

可能在一两天之内,我们还是会记得解决这些问题的方法,但是过了一段时间之后,基本上都忘光了。

所以这里,我们应该要养成一个良好的习惯,把每次遇到的问题,如何解决的,都记录下。下次再看文档,这样就想起来了。

<<千与千寻>>有些事情是不可能忘记的,只是一时想不起来

下面,就分享一下,我遇到的一些问题,和相关的解决方法。

1.Springboot修改配置,并重新设置回spring容器

例如,我们需要对spring.datasource.password数据库连接密码,进行加密配置。那在spring容器启动的时候,就需要对该值进行解密,然后重新设置回spring容器中,好让spring容器启动成功。

这里,我们可以使用EnvironmentPostProcessor来实现。

  • DbPasswordPostProcessor.java
public class DbPasswordPostProcessor implements EnvironmentPostProcessor {

    public static final String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password";

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        System.out.println("environment = " + environment + ", application = " + application);
        System.out.println(environment.getPropertySources());
        for (PropertySource<?> propertySource : environment.getPropertySources()) {
            if (propertySource instanceof OriginTrackedMapPropertySource) {
                String password = (String) propertySource.getProperty(SPRING_DATASOURCE_PASSWORD);
                System.out.println("加密的密码 : " + password);
                HashMap<Object, Object> map = MapUtil.newHashMap(1);
                map.put(SPRING_DATASOURCE_PASSWORD, AesUtil.decrypt(password));
                System.out.println("解密后的密码: " + AesUtil.decrypt(password));
                OriginTrackedMapPropertySource originTrackedMapPropertySource = new OriginTrackedMapPropertySource(SPRING_DATASOURCE_PASSWORD,
                        map);
                environment.getPropertySources().addFirst(originTrackedMapPropertySource);
            }
        }
    }
}

AesUtil.decrypt解密,是一个Aes加解密的工具类,可自行实现即可。

  • spring.factories(src/main/resources/META-INF/下面)
org.springframework.boot.env.EnvironmentPostProcessor=com.llsydn.config.DbPasswordPostProcessor

注意:这里spring.datasource.password=${db.password},如果这个配置放在nacos这些配置中心,会出现使用EnvironmentPostProcessor获取不到nacos上的配置信息。

即这个时候,走到EnvironmentPostProcessor的时候,都还没去获取nacos的数据,所以你想用这种方式去实现解密肯定是不行的,ApplicationContextInitializer这个倒是还挺不错,回调时机在读取nacos数据后面执行。

  • DbPasswordInitializer.java
public class DbPasswordInitializer implements ApplicationContextInitializer {

    public static final String DB_PASSWORD = "db.password";

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        System.out.println("environment = " + environment + ", application = " + applicationContext);
        System.out.println(environment.getPropertySources());
        for (PropertySource<?> propertySource : environment.getPropertySources()) {
            if (propertySource instanceof BootstrapPropertySource) {
                String password = (String) propertySource.getProperty(DB_PASSWORD);
                if (StringUtils.isNotEmpty(password)) {
                    System.out.println("加密的密码 : " + password);
                    HashMap<Object, Object> map = MapUtil.newHashMap(1);
                    map.put(DB_PASSWORD, AesUtil.decryptIfNeed(password));
                    System.out.println("解密后的密码: " + AesUtil.decryptIfNeed(password));
                    OriginTrackedMapPropertySource originTrackedMapPropertySource = new OriginTrackedMapPropertySource(DB_PASSWORD,
                            map);
                    environment.getPropertySources().addFirst(originTrackedMapPropertySource);
                }
            }
        }
    }
}
  • spring.factories(src/main/resources/META-INF/下面)
org.springframework.context.ApplicationContextInitializer=com.llsydn.config.DbPasswordInitializer

ApplicationContextInitializer 和 EnvironmentPostProcessor

两者都是在refresh spring的上下文之前调用,是spring boot预留的扩展接口,需要在必须要在META-INF/spring.factories文件中去注册,并且注册的是全类名。

两者的调用顺序是,先调用EnvironmentPostProcessor 的实现类,在去调用ApplicationContextInitializer的实现类。

2.mysql忘记密码怎么重置

#关闭mysql
systemctl stop mysqld

#无验证方式启动mysql服务
mysqld --skip-grant-tables

#进入mysql控制台
mysql

#修改密码
use mysql; 
alter user 'root'@'localhost' identified by "mysql12qw!@P@ssw0rd";
flush privileges;
 
#重启mysql 
systemctl restart mysqld

k8s搭建mysql主从同步

3.RestControllerAdvice全局异常如何排除指定的异常?

有时候,我们使用了@RestControllerAdvice全局异常拦截,这样就会导致所有通过throw的异常,都被拦截了。

如果一些底层框架,就是要throw抛出异常,底层框架才能处理后面的业务逻辑;@RestControllerAdvice全局异常,就影响了后面的业务逻辑代码执行,即是截断了底层的实现。

例如:oauth2框架,在调用/oauth/authorize接口时,如果没有登录,会跳到login登录页面。但是由于@RestControllerAdvice全局异常,导致返回了json异常数据,无法跳转到login登录页面。

常用操作合集五

oauth2,未登录,抛出的异常是InsufficientAuthenticationException

那@RestControllerAdvice全局异常,怎么可以排除我们指定的异常呢?

@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {
    .....
    /**
     * 处理oauth2异常
     * @return
     */
    @ExceptionHandler(InsufficientAuthenticationException.class)
    public void handleInsufficientAuthenticationException() {
        throw new InsufficientAuthenticationException("oauth2异常");
    }
}

定义一个InsufficientAuthenticationException异常的ExceptionHandler拦截,在方法中,重新throw抛出InsufficientAuthenticationException异常即可。

4.mysql查询优化,索引使用情况

  • using index、using where、using index condition
using index :使用覆盖索引的时候就会出现,测试发现主键索引也会生效

using where:在查找使用索引的情况下,需要回表去查询所需的数据

using index condition:查找使用了索引,不需要回表查询,因为要过滤的字段在索引中

using index & using where:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据(联合索引很容易出现这样的结果)
SELECT B.AAC002, B.AAC003, A.BCC002, B.CAC001 AS CAC001, A.AAE005, A.BCC205, A.CCD018, A.BDE126, A.BHD305    
FROM CCA2 A    
LEFT JOIN GXK.AC01 B ON A.AAC001 = B.AAC001 
  • explain结果如下:

常用操作合集五

1.由于数据库两张表的字段编码不一致导致的。

#查看这两个表的字段编码
show full columns from CCA2; 
show full columns from GXK.AC01;

2.由于Using filesort排序导致的。

去掉ORDER BYUsing filesort自然会消失。
filesort消失了,但是查询速度还是没有跟上来,所以主要的原因还是没有找到。

3.由于没有走索引导致的。

Using join buffer (hash join):在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫join buffer的内存块来加快查询速度,也就是我们所讲的基于块的嵌套循环算法

上面的查询,应该是没有用到索引。

参考文档

  • 输出的各个列的作用
列名描述
id在一个大的查询语句中每个SELECT关键字都对应一个唯一的id
select_typeSELECT关键字对应的那个查询的类型
table表名
partitions匹配的分区信息
type针对单表的访问方法
possible_keys可能用到的索引
key实际上使用的索引
key_len实际使用到的索引长度
ref当使用索引列等值查询时,与索引列进行等值匹配的对象信息
rows预估的需要读取的记录条数
filtered某个表经过搜索条件过滤后剩余记录条数的百分比
Extra一些额外的信息
  • type

结果值从上到下依次变坏,至少达到 range 级别,要求 ref 级别,最好是 const 级别。

类型说明
system当表中只有一条记录并且该表使用的存储引擎的统计数据是准确的如MyISAMMemory,那么对该表的访问方法就是system
const当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是const
eq_ref在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是eq_ref
ref当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是ref
fulltextThe join is performed using a FULLTEXT index.
ref_or_null当对普通二级索引进行等值匹配查询,该索引列的值也可以是NULL值时,那么对该表的访问方法就可能是ref_or_null
index_merge单表访问方法时在某些场景下可以使用IntersectionUnionSort-Union这三种索引合并的方式来执行查询
unique_subquery针对在一些包含IN子查询的查询语句中,如果查询优化器决定将IN子查询转换为EXISTS子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的type列的值就是unique_subquery
index_subqueryThis join type is similar to unique_subquery. It replaces IN subqueries, but it works for nonunique indexes in subqueries
range如果使用索引获取某些范围区间的记录,那么就可能使用到range访问方法
index当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是index
ALL全表扫描

5.docker容器操作Permission denied无权限问题

解决办法:

加上 --user=root 参数

docker exec -it --user=root nginx /bin/bash

如果不行,最后的参数可以换成/bin/sh

harbor重启:

#首先停掉harbor
docker-compose down
#启动harbor
docker-compose up -d

6.docker清理占用空间

docker占用磁盘太大,如何清理

docker 占用的空间可以通过下面的命令查看:

docker system df

常用操作合集五

TYPE 列出了docker 使用磁盘的 4 种类型,TOTAL 表示该类型资源的总数,ACTIVE 表示当前正在使用的数量,SIZE 表示该类型资源的总大小,RECLAIMABLE 表示可以回收的空间大小。

  • Images: 所有镜像占用的空间,包括拉取下来的镜像,和本地构建的。
  • Containers: 运行的容器占用的空间,表示每个容器的读写层的空间。
  • Local Volumes:容器挂载本地数据卷的空间。
  • Build Cache: 镜像构建过程中产生的缓存空间(只有在使用 BuildKit 时才有,Docker 18.09 以后可用)。

镜像的磁盘占用 删除悬挂状态的镜像,即 none 状态的镜像

docker image prune

如果想删除所有镜像,可以使用下面的命令:

docker image rm $(docker image ls -q)

注: 正在被容器使用的镜像是不能被删除的。

容器的磁盘占用 删除所有停止的容器

docker container prune

如果想删除所有容器(包括停止的、正在运行的)

docker rm -f $(docker ps -aq)
#或者 
docker container rm -f $(docker container ls -aq)

数据卷的磁盘占用 删除不再使用的数据卷

docker volume prune

Build Cache 的磁盘占用 删除 build cache 可以使用命令

docker builder prune

一键清理 通过上面的说明,我们知道了像容器、镜像、数据卷都提供了 prune这个子命令,帮助我们回收空间。 其实,docker 系统层面也有 prune 这个子命令,可以一键清理没用的空间:

docker system prune

这个命令用于清理 Docker 系统中的未使用资源,包括未使用的镜像、停止的容器、未被使用的网络和挂载点等。 这个命令慎用。

检查正在运行的容器大小

想知道正在运行的 Docker 容器的大小,可以使用 docker ps 命令:

docker ps --size
>  docker ps --size
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
CONTAINER ID  IMAGE                           COMMAND               CREATED         STATUS             PORTS                 NAMES       SIZE
8900fc2086b3  docker.io/library/nginx:latest  nginx -g daemon o...  14 seconds ago  Up 14 seconds ago  0.0.0.0:8099->80/tcp  nginx-test  1.11kB (virtual 142MB)

7.maven打包jar和源码包,发布到nexus私服

  • pom.xml加入相关插件
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.2.0</version>
<!-- 绑定source插件到Maven的生命周期,并在生命周期后执行绑定的source的goal -->
            <executions>
                <execution>
             	<!-- 绑定source插件到Maven的生命周期 -->
                    <id>attach-sources</id>
                    <phase>package</phase>
                <!--在生命周期后执行绑定的source插件的goals -->
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

maven-source-plugin作用: 在构建过程中将项目的源代码进行打包,并作为一个jar文件附着在主构件上,在 pom.xml 中添加如下内容,使用 maven 生成 jar 的同时生成 sources 包

常用操作合集五

使用install命令,就可以将相应的jar包和sources源码包,打包到本地的maven仓库。

  • nexus私服地址配置,在pom.xml加入下面配置
<distributionManagement>
    <!--nexus私服-->
    <repository>
        <!--正式版本-->
        <id>releases</id>
        <url>http://127.0.0.1:8081/nexus/content/repositories/maven-releases</url>
    </repository>
</distributionManagement>

maven的setting.xml文件节点配置

<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <localRepository>E:\Program Files\maven\repository</localRepository>
    <interactiveMode>true</interactiveMode>
    <offline>false</offline>
    <pluginGroups>
        <pluginGroup>org.mortbay.jetty</pluginGroup>
        <pluginGroup>org.jenkins-ci.tools</pluginGroup>
    </pluginGroups>
    
    <!--配置权限,使用默认用户-->
    <servers>
        <!--llsydn-->
        <server>
            <id>nexus-releases</id>
            <username>admin</username>
            <password>admin</password>
        </server>
    </servers>

    <mirrors>
        <!--nexus私库-->
        <mirror>
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <url>http://127.0.0.1:8081/nexus/repository/maven-public/</url>
        </mirror>
        <!--阿里云公共仓库-->
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

    <profiles>
        <!--llsydn-->
        <profile>
            <id>llsydn</id>
            <repositories>
                <!--nexus私库地址-->
                <repository>
                    <id>nexus</id>
                    <url>http://127.0.0.1:8081/nexus/repository/maven-public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <!--nexus插件库地址-->
                <pluginRepository>
                    <id>nexus</id>
                    <url>http://127.0.0.1:8081/nexus/repository/maven-public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                   </snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    
    <!--激活profile-->
    <activeProfiles>
        <activeProfile>llsydn</activeProfile>
    </activeProfiles>
</settings>

常用操作合集五

使用deply命令,就可以将相应的jar包和sources源码包,发布到nexus私服。

8.mysql集群方案

MySQL集群方案:

1、MySQL Replication主从方案,mysql官方方案,一般大家使用的是这种,主挂了这种是不带自动选主的功能

2、MySQL Fabirc主从方案,mysql官方方案,是带自动选主的功能

3、MySQL Cluster多主多从方案,mysql官方方案,这个方案是多主,挂了一个还有别的

4、MHA主从方案,第三方的方案,这个方案也是带主挂了,自动选主功能

9.mysql跨库查询方案

federated方案

10.没有telnet,nc,namp命令下检测端口

/dev/tcp/<hostname>/<port>

hostname替换ip,port替换端口号

特殊的文件,允许通过该接口进行TCP网络通信

echo > /dev/tcp/127.0.0.1/3306

结果没有返回,说明端口是通的。

结果返回如下,说明端口是不通的。

-bash: connect: Connection refused
-bash: /dev/tcp/127.0.0.1/3306: Connection refused

注:该命令不适用于docker容器里面

容器里面可以采用下面的命令:结果和上面一样(alpine镜像除外)

-i >& /dev/tcp/127.0.0.1/3306 0>&1; 

11.docker迁移默认的/var/lib/docker 到指定数据盘目录

#1、先停止docker 服务
systemctl stop docker

#2、创建docker挂载数据盘目录
mkdir -p /data/docker/lib

#3、 安装迁移工具
yum install rsync -y

#4、 迁移数据到新目录
rsync -azP /var/lib/docker /data/docker/lib

#5、修改docker 配置文件docker.service 
vim /usr/lib/systemd/system/docker.service
在ExecStart=/usr/bin/dockerd 后添加--graph=/data/docker/lib/docker

#6、重启docker 服务
systemctl daemon-reload && systemctl restart docker

#7、确定docker 正常,删除原目录
rm -rf /var/lib/docker

12.Harbor如何通过命令行创建项目

有时候在工作中,我们会遇到在没有内网windows机器的情况下,想要创建项目。这时候就需要命令行来进行直接创建。

说明:我这里的harbor版本是v2.6.2的

  • 命令行创建私有项目

假设需要创建名为jxbp的私有项目

curl -k -u 'admin:Harbor12345' -XPOST -H "Content-Type:application/json" -d '{"project_name":"llsydn", "public": false}' "http://127.0.0.1:88/api/v2.0/projects"

上面参数说明:

  • -k:用于执行不安全的 SSL 连接,通常在使用自签名证书时使用。
  • -u 'admin:Harbor12345':提供了基本身份验证的用户名和密码。确保将这里的用户名和密码替换为你的 Harbor 实例的实际凭证。
  • -XPOST:指定 HTTP 请求的方法为 POST。
  • -H "Content-Type:application/json":设置请求的内容类型为 JSON。
  • -d '{"project_name":"llsydn", "public": true}':提供与 POST 请求一起发送的数据。在这里,JSON 对象指定了项目名称为 "llsydn" 并将其设置为私有。
  • "http://127.0.0.1:88/api/v2.0/projects":指定发送 POST 请求的 URL。确保将这里的 URL 替换为你的 Harbor 实例的实际 URL。

好了,以上就是我个人的实操了。可能有些不对,大家伙,轻点喷!!!

个人理解,可能也不够全面,班门弄斧了。

好了,今天就先到这里了!!!^_^

如果觉得有收获的,帮忙点赞、评论、收藏一下,再走呗!!!

常用操作合集五

转载自:https://juejin.cn/post/7343243744479166515
评论
请登录