日常工作常用工具介绍

1.Git

为了方便书写,给出的都是命令行形式,实际上常用命令在各种git客户端里都有对应的操作。

1.1分支操作

#创建分支
git checkout -b dev origin/dev

#分支切换
git checkout dev

#查看本地分支
git branch

#查看所有分支
git branch -a

#查看分支映射
git branch -vv

#删除分支
git branch -d dev

#清理废弃远程分支映射
git remote prune origin 

#合并
#使用客户端操作,命令行解决冲突比较麻烦

1.2提交

#查看变更
git status

#将工作区变更添加进暂存区
git add {
    
    filename}

#将暂存区变更添加到本地分支
git commit -m "commit message"

#将本地分支变更推送到远程分支
git push

1.3撤销提交

#撤销一次commit
git revert {
    
    commit_id}

#撤销一次merge commit
git revert {
    
    commit_id} -m {
    
    parent_no}

1.4实用操作

  • 查找代码变更位置

    • 场景:想知道一处变更是什么时候改的?谁改的?

    • 操作:以egit为例

      选中要查看的文件->右键->Team->Show in History,打开该文件的变更历史。

      选中一次commit可以查看变更的文件,双击打开可以查看文件当时的状态,往回追溯即可找到变更位置,时间和提交人都可以查到。

      选中commit变更文件列表里的文件右键->Compare with Previous Version 可以查看这次commit中该文件的详细变更情况。

  • 复制提交

    • 场景:想要复制分支中部分commit

    • 操作

      1、切换到需要合入的分支

      2、找到想要复制的commit

      3、命令:git cherry-pick {commit_id}

      ​ egit:在git history中选中commit->右键->Cherry-Pick

2.Maven

2.1生命周期

Build生命周期

生命周期阶段 描述
validate 检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到。
initialize 初始化构建状态,例如设置属性。
generate-sources 生成编译阶段需要包含的任何源码文件。
process-sources 处理源代码,例如,过滤任何值(filter any value)。
generate-resources 生成工程包中需要包含的资源文件。
process-resources 拷贝和处理资源文件到目的目录中,为打包阶段做准备。
compile 编译工程源码。
process-classes 处理编译生成的文件,例如 Java Class 字节码的加强和优化。
generate-test-sources 生成编译阶段需要包含的任何测试源代码。
process-test-sources 处理测试源代码,例如,过滤任何值(filter any values)。
test-compile 编译测试源代码到测试目的目录。
process-test-classes 处理测试代码文件编译后生成的文件。
test 使用适当的单元测试框架(例如JUnit)运行测试。
prepare-package 在真正打包之前,为准备打包执行任何必要的操作。
package 获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。
pre-integration-test 在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量。
integration-test 处理和部署必须的工程包到集成测试能够运行的环境中。
post-integration-test 在集成测试被执行后执行必要的操作。例如,清理环境。
verify 运行检查操作来验证工程包是有效的,并满足质量要求。
install 安装工程包到本地仓库中,该仓库可以作为本地其他工程的依赖。
deploy 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

这几个阶段是从上到下按顺序执行,不同的命令到不同的阶段,但是之前的阶段一定是会执行的。

我们主要关注下面几个命令

  • compile

    编译,生命周期执行到compile为止。

    我们可以用它来验证工程是否能正确编译。

  • test

    测试,包含compile,默认执行src/test/java目录下的testcase。

    我们目前这一块比较混乱,可以跳过这一步,maven命令中加上参数-Dmaven.test.skip=true

  • package

    打包,包含test、compile,按设置将编译后的代码打包。

    可以本地打包验证包是否正常,例如:报名是否符合预期,配置文件是否按逾期打包等

  • install

    发布包到本地仓库,包含test、compile、package,包会被发布到本地maven仓库中。

    本地开发时可以将新开发的依赖包发布到本地仓库自己使用。

  • deploy

    发布包到远程仓库,包含test、compile、package、install。

    这一步操作有权限限制,通常来说对应的是公司内部部署的maven私服nexus,如果有权限,可以直接将包发布到私服上供其他人使用。

    我们目前已经回收了该权限,只保留了服务器上的权限,要发包到私服通过jenkins来实现。

2.2常用命令

  • mvn clean

    mvn clean可以单独执行,功能是清空target。

    也可以叠加执行,例如:mvn clean package,它会先清空target然后再执行package命令,避免旧包干扰。

  • eclipse插件

    无须配置,可直接使用。

    #生成eclipse配置文件:.settings、.project、.classpath等
    mvn eclipse:eclipse
    
    #清理eclipse配置文件,可以得到比较干净的代码
    mvn eclipse:clean
    
  • IDEA插件

    无须配置,可直接使用。

    #生成idea配置文件:.iml、.ipr、.iws等
    mvn idea:idea
    
    #清理idea配置文件,可以得到比较干净的代码
    mvn idea:clean
    
  • dependency插件

    无须配置,可直接使用。

    #查看工程依赖树
    mvn dependency:tree
    
    #导出工程依赖,默认路径:target/dependency
    mvn dependency:copy-dependencies
    
  • jetty插件

    需要在pom.xml中配置插件,如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.8.v20150217</version>
                <configuration>
                    <httpConnector>
                        <port>8080</port>
                        <host>localhost</host>
                    </httpConnector>
                    <scanIntervalSeconds>1</scanIntervalSeconds>
                    <systemProperties>
                        <systemProperty>
                            <name>zk_group</name>
                            <value>sit</value>
                        </systemProperty>
                    </systemProperties>
                    <webApp>
                        <contextPath>/cbms-web</contextPath>
                    </webApp>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    #无须外部容器即可启动web程序,支持热部署
    mvn jetty:run
    

2.3如何查看依赖

2.2中的dependency插件可以查看,但是不够详细。

我们日常使用时可以使用客户端来查看,方便使用且功能更强大。

以eclipse为例:

打开pom.xml,选择下方的页签Dependency Hierarchy,可以看到详细依赖树,在右上角还有筛选功能,最重要的是它标注了版本号的覆盖情况,方便分析问题。

在这里插入图片描述

如图,我筛选出了slf4j-api,专注分析整个依赖,从左边的依赖树可以看到,这个依赖有4处依赖,其中log4j-over-slf4j-1.7.7依赖了slf4j-api-1.7.7、logback-classic-1.1.2依赖了slf4j-api-1.7.6,因为ares-parent中依赖了slf4j-api-1.7.2,这个依赖层级最高,将log4j-over-slf4j-1.7.7和logback-classic-1.1.2的依赖强制改为了slf4j-api-1.7.2。

补充说明:我们现在的工程结构使用了Maven CI Friendly Versions结构,发布时通过flatten-maven-plugin插件简化了pom.xml,所以本地代码中的pom.xml依赖不准确,最终依赖以仓库中的pom.xml为准,如果需要可以将仓库中的pom.xml拷贝出来分析。

2.4快照包

在maven仓库中,包名以-SNAPSHOT结尾的包是快照包,会特殊处理。

找到快照包在仓库中的目录,会发现有很多包名中带时间戳的包,这就是快照包的特殊之处,它的一个版本号里会有很多包,代表该版本号的包是时间戳最新的包。这种设计是为了可以覆盖旧包,主要用于内部开发阶段,代码非常不稳定,但是又需要给出来用。

PS:因为快照包会一直覆盖旧包,那么就肯定会出现本地包不是最新的情况,毕竟你的包名没变,本地maven除非每次都去服务器上查一次,不然是不能保证本地包最新的。如果需要拿到最新的快照包,可以在maven命令中加上-U,强制要求更新。

既然特殊处理的快照包设计成可以覆盖旧包,那么对应的其他版本包应该就是不能覆盖的了?确实是这么设计的,如果不能理解这点在日常使用中会有很大的困惑。

我们设想一个场景,spring官方发布了1.0.0版本—spring-1.0.0,我们用了这个包,使用了里面的ClassPathXmlApplicationContext类;

然后spring官方又觉的ClassPathXmlApplicationContext这个类设计的不好,给干掉了,然后他们觉的改动不大,偷懒没有升级版本号,用新代码发布了新的spring-1.0.0。这个时候我们就麻烦了,有的同事按要求去下载到新的spring-1.0.0后发现没有ClassPathXmlApplicationContext,代码没法使用,用旧包的人没问题,明明都是1.0.0的包。

为了避免这种情况,maven设计上给你留了可以覆盖的快照包开发用,其他的非快照包是不能覆盖的,你给出去让别人用的包不能乱改,只能升级版本号发布新包。具体的限制是本地仓库不会更新非快照包,即使你手动去私服上把这个包干掉重新上传一个;私服默认也不能deploy已经有的非快照包。

3.服务配置参数查找

@Value("#{env['redis_expire_time']?:3600}")
private int redisExpireTime;
<property name="driverClassName" value="#{env['jdbcDriver']}"/>

我们系统中大部分参数都是通过上面这种形式来取参数,这种形式的参数来源其实比较复杂,不熟悉的话,往往都不太清楚具体一项参数是从哪里来的。

我们来了解下参数都是从哪里来的:

先从env参数开始

<bean id="env" class="com.allinfinance.ares.facility.config.AresEnvironmentFactoryBean">
    <property name="locations" value="#{systemProperties['env.files'] ?: 'classpath:/conf/*.properties'}" />
</bean>

这是我们使用的参数的起点,可以看到,这里是在设置配置文件路径,默认从环境变量里取env.files的值,如果没有就取conf目录下的所有properties文件。我们目前没发现有配置env.files,这里直接当做取conf目录下properties文件。

PS:systemProperties在AbstractApplicationContext.prepareBeanFactory方法中注册的。

接着进AresEnvironmentFactoryBean类看看

public class AresEnvironmentFactoryBean extends PropertiesLoaderSupport
        implements FactoryBean<Properties> {
    
    

    private Logger logger = LoggerFactory.getLogger(AresEnvironmentFactoryBean.class);

    @Override
    public Properties getObject() throws Exception {
    
    
        Properties props = new Properties();
        Map<String, String> env = System.getenv();
        // 从配置的本地文件取值
        super.loadProperties(props);

        // 环境变量定义的优先
        if (StringUtils.isNotEmpty(env.get("instanceName"))) {
    
    
            logger.info("发现instanceName环境变量,开始从环境变量取值.");

            props.putAll(System.getenv());
        }

        // 命令行上的参数优先级最高
        props.putAll(System.getProperties());

        String dpf = props.getProperty("decryptFieldName");
        if (dpf != null && dpf.trim().length() > 0) {
    
    
            String decryptFieldName[] = dpf.trim().split(",");
            for (int i = 0; i < decryptFieldName.length; i++) {
    
    
                String s1 = props.getProperty(decryptFieldName[i]);
                String s2 = ThreeDes.decryptMode(decryptFieldName[i], s1);
                props.setProperty(decryptFieldName[i], s2);
            }
        }

        return props;
    }

    @Override
    public Class<?> getObjectType() {
    
    

        return Properties.class;
    }

    @Override
    public boolean isSingleton() {
    
    

        return true;
    }

}

这是一个FactoryBean的实现,从getObjectType方法看最后产生的是一个Properties类,生成过程在getObject中,首先调用了PropertiesLoaderSupport的loadProperties方法,这是spring的类,会处理之前配置的通配符并加载这批配置文件到props对象中。

然后判断系统环境变量里是否有instanceName这个配置,如果有,就将环境变量里的配置覆盖进props对象中。

接下来是将命令行参数覆盖进props对象中。再后面是处理一些3DES加密过的参数。处理完成后将props对象输出。

从这段逻辑可以看出,我们系统中类似#{env['zk_group']}这种从env对象中获取参数的形式遵循一套规则,参数来源有4个途径:配置路径的配置文件中读取的参数、系统环境变量、虚拟机启动参数、加密参数,他们的优先级规则是:加密参数>虚拟机启动参数>系统环境变量>配置路径的配置文件中读取的参数。

知道这个规则后,去找参数就简单了,按图索骥:

  1. 配置路径的配置文件中读取的参数

    这部分配置通常都是读工程内部conf目录下的properties文件,直接去工程里找即可。

  2. 系统环境变量

    我们的服务器操作系统使用的是CentOS,我们都知道添加环境变量有三种方法:

    • 在/etc/profile中添加export语句,整个系统生效
    • 在当前用户根目录下的.bash_profile文件中添加export语句,对当前用户生效
    • 在shell脚本中export语句,临时使用

    去这几个地方检察下,发现这部分参数有两个来源:

    • .bash_profile->.bashrc->~/apphome/lkl.env

    • ~/apphome/bin目录下的启动脚本,这里边主要引入了common.env和一个私有env,一种比较便捷的查询方式是进入conf目录搜索所有的env文件,例如要查消息队列的配置

      cd ~/apphome/conf
      cat *.env|grep queue
      

    PS:如果想要查看当前生效的系统环境变量可以通过命令查看

    #linux系统查看当前生效环境变量:echo ${key}
    echo $JAVA_HOME
    
    #window系统查当前生效环境变量:echo %{key}%
    echo %JAVA_HOME%
    
  3. 虚拟机启动参数

    这部分可以通过启动脚本查到来源,通常来说它会混合环境变量、脚本配置来组装启动命令。

    一种比较便捷的查询方式是直接查进程看启动脚本,例如:ps -ef|grep banknf-web,因为我们是通过jsvc来启动服务,它会启动一个守护进程,通过这个命令查看时会发现有两个进程,注意看两个进程的PPID,PPID是1的是守护进程,PPID是守护进程PID的进程即是虚拟机进程。

  4. 加密参数

    没发现有这个参数的使用,一般忽略它。

4.zkCli

因为我们的服务大多基于dubbo,dubbo的服务发现基于zookeeper,当服务异常时,检查下zookeeper里的数据节点有助于排查问题。

zookeeper官方提供了客户端访问工具zkCli,下载zookeeper包,解压后将其内部的bin目录配入环境变量接口在cmd环境使用zkCli命令。

#连接zookeeper服务
zkCli -server 192.168.0.150:2181,192.168.0.151:2181,192.168.0.152:2181

zk服务正常的话,会出现一个命令行环境。

按dubbo服务发布规则查看注册上来的服务(/{group}/{interface})

#查询sit环境adm的服务GenerateSequenceService发布情况
ls /sit/com.allinfinance.adm.service.api.GenerateSequenceService/providers

如果得到的是空的,说明没有活跃服务,adm服务应该是挂了,去检查该服务。

如果得到一个有值的数组,这就是dubbo服务发布方信息,因为做了unicode加密,里面有很多奇怪的%之类的符号,这些都是标点符号之类的符号转换的,其他的信息可以正常阅读,如果觉的碍眼可以找一个unicode加解密工具还原,这种工具有很多在线版。

使用完毕后,输入quit退出。

5.redis-cli

与zkCli类似,Redis也提供了自己的客户端工具redis-cli,配入环境变量即可在cmd环境使用。

#连接redis
redis-cli -h 192.168.0.150 -p 6384 -c

#查键(例如查sit环境所有键),这个命令会影响redis运行,不要在生产环境使用,如果要在生产环境查询请使用scan命令
keys sit:*

#查键值,如果没有该键返回(nil)
get sit:dcn_mode:135

#删除键
del {
    
    key}

#查看键存活时间(-1表示未设置存活时间,-2表示已失效)
ttl {
    
    key}

实际用途:

  • 查adm映射

    我们adm缓存映射key组成规则:{namespace}:{keyType}:{keyValue}

    举例:查sit环境借据号0120320810000077041对应的cust值,get sit:D:0120320810000077041

    一种比较常见异常:分区错误,查看日志发现分区要素keyValue没有传值,把keyValue设置成null查下,应该是查到错误的custId了。

  • 查服务开关

    我们的服务开关判断依据是redis中的key值,当BMP中配置不符合预期时,可以去redis中查询对应开关的key值验证问题。

    服务控制key规则:{namespace}:{org}:{服务编号}:{渠道号}

    举例:sit环境000000000001机构预授权(APP)拉卡拉钱包APP的key是sit:000000000001:04B101:01

    当服务控制key值是Y时表示服务开通

    提示:当渠道服务key值表示关闭时不一定服务不可用,还要检查下该服务开通全部渠道(渠道号为00)的情况

7.eclipse插件

  • Eclipse Explorer

    快捷跳转工具,在Explorer窗口选择想要跳转的目录->右键->Open in Explorer,即可直接到达文件位置。

    提示:依赖也可以跳转,会直接跳到本地仓库该包的位置

猜你喜欢

转载自blog.csdn.net/tangyb828/article/details/108340565