解惑

解己之惑,解人之惑

分类:软件开发 (第1页共4页)

TransportClient要被淘汰了

发现我们使用的ElasticSearch的版本快过期了(end of life),计划升级,发现ElasticSearch将要淘汰原来的TransportClient转而力推High Level Rest Client了。

其它的问题都还好说,包的依赖和Client的初始化的不同影响面比较小,但是接口的不兼容影响比较大,不知道需要多少代价才能改完,不过好在都有各种测试代码了,修改应该可以。

 

基于Spring Boot的支持ElasticSearch和JWT的POM

不多说废话了,直接贴内容吧,用的库的版本基本是最新的了:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>auth0-spring-security-api</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.4.1</version>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>elastic.co</id>
        <url>https://artifacts.elastic.co/maven</url>
    </repository>
</repositories>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>8</source>
                <target>8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

BASH的一些知识总结

不知不觉一个月就过去了,发现什么都没有写,趁放假补一下功课吧。

最近的几个月搞了不少BASH的东西,因为我把系统的升级功能重写了下,原来的代码实在是惨不忍睹。总结几个在重写的过程中的BASH知识点。

  1. 根据变量名得到变量值,这个在使用动态功能的时候特别有用,其实也很简单 ${!variablename}
  2. 使用管道后得到管道的某个输出的exit code:${PIPESTATUS[0]}, 0就是拿管道最开始的那个命令的返回值,如果不使用这个,那么exit code永远是0
  3. 使用“可以得到命令执行的输出结果,比如`hostname -s`,另外一种方式是$(hostname -s)
  4. 可以直接使用某个方法的返回值做if的条件判断,比如 if my_function; then
  5. 在引用变量值的时候尽可能给变量加上引号,特别是想把变量值往其他的方法传的时候,例如 my_function “$my_variable”,因为使用的那个变量值包含空格之类的就可能不是你期望的结果了。
  6. 得到当前代码行的行号:$LINENO
  7. 方法只能返回int值,不能返回string,所以方法想返回string的时候只能借助global的变量
  8. exit code的返回值范围是0到255
  9. 放在双引号里的变量会被解析,如果不想被解析,就用单引号
  10. 只有方法里面的变量才能定义为local,最外层的变量只能是global,方法里面定义的变量默认也是global
  11. 在条件判断里面做字符串大小比较,<前面要加个\:if [ “$onestring” \< “$anotherstring” ] ; then
  12. 把一个local变量的值赋值给一个global变量的时候必须在local变量前加$:globalvar=$localvar
  13. 在复杂功能里面尽量不要用xargs,因为它会起子shell,变量赋值不能传到外面的功能,尽可能用while do
  14. 做数字运算其实都是个没那么简单的事情:let “filecount-=1″,变量减一操作,其它类似,使用let加上运算表达式
  15. 判断是否是空值:if [ -z $somevar] ; then
  16. 需要把多行的语句放到一行的,应该换行的地方加个分号
  17. 方法后面的参数可以接其它的方法,后面的方法甚至还可以带参数,只要在方法里面调用”$@”就可以
  18. 获得上一个语句的返回值:$?
  19. 循环处理数组中的每个值:for value in “${my_array[@]}”
  20. 判断一个变量值是否设置了:if [ -z ${myvar+x} ]; then echo “not set”; fi
  21. 如果要计算两个数并赋值给其他的变量:thirdvar=$(expr $firstvar + $secondvar)
  22. 条件判断中的字符判断直接用=,数字比较就得 -eq, -gt等,文件目录判断 -f,-d
  23. 计算数组的大小:${#myarray[@]}
  24. 把数组里面的值拼成字符串,可以使用”${nodes[@]}”,但是如果你要把这个作为方法的参数传递则不行,必须先把这个结果赋值给一个变量再传递那个变量值:allvalues=”${myarray[@]}”; my_function “$allvalues”

好像还不少,任何一个语言,要用好都不容易,但是如果你知道自己要什么,其实也不难,有google啊。

智能化和极简化

曾几何时,企业级软件是一个非常高大上的名词,而难用是后面的潜台词,从部署到配置到使用,非常的受诟病,但是没办法,在软件开发不那么成熟的时代,能够有能力组织开发出如此复杂的软件的就那么几个公司,能够做出来已经很不错了,加上采购者和使用者完全是两拨人,使用者的话语权太低了,所以以用户为导向的重要性虽然在产品开发的过程中被重视,但是视角完全是错误的,重点完全在功能的完整性、多样性和灵活性上。当互联网真正崛起,SaaS被广为接受,服务化被广泛采用后,我们才发现他们的玩法不一样了,因为直接面对的是最终使用者,最终使用者的口碑传播效应得到了极大提升,以使用者作为真正用户的视角才被纠正,所以各种讨好最终使用者的特性才被重视起来了,早期一个很重要的概念就是傻瓜化,这个,乔布斯的iPhone也是居功至伟的,但是我更愿意叫这个为智能化,伴随而来的还有极简化,核心思想就是尽最大可能减少用户的思考和使用门槛,上手就能够用而且用的比较顺畅。由于我以前也搞过自己的社区,深深知道这个有多么的重要,而很不幸的是这么多年都在大公司,很多思想并不被接受,终于,从前几年开始,这些风终于刮到了企业级这个漆黑的领域。从3年前做的一键升级整个集群,使得原来一个40台节点集群的升级时间从7天缩短到8个小时(大部分其实是升级准备及数据库,服务器升级半个小时内就可以搞定,并行的),而且基本不需要人工干预(除非客户有自己的定制化配置),为此Support的头头还专门写信表扬过,到现在,新的产品的一个极大的重心也是在智能化和极简化上,包括安装和升级,总算开始和自己一贯的思想理念一致了,特此纪念下。。。

ElasticSearch只允许每个index里面一个type了

这个是今天内部讨论获悉的信息,查了下属实,具体内容可以看官方文档:

Removal of mapping types

5.x以前的multiple types还可以正常工作,但是6.x里面新创建的index只允许一个type了,从7.0开始将强制只有一个type。

这个对于很多打算把ElasticSearch做数据库使用的团队来讲不会是个特别好的消息,因为数据库的很多表其实只有很少的数据,大量数据可能集中在几个大表里面。不过既然趋势如此,如果打算继续用ElasticSearch就必须接受这个变化并遵循。

想想从ElasticSearch 0.9开始用到现在,也就短短5年(已经5年了😯)吧,版本也是一路突飞猛进,到现在6.3,估计7.0也会在年内发布,感受到ElasticSearch的高度活跃,推出的功能也是越来越多,我们原来基于ElasticSearch做的那些功能现在看起来太落伍了,刚好产品也进入维护模式了,估计要重新做了,刚好我原来对这个产品的很多设计非常不满(不是我设计的😛)

不过我的一些想法倒还没有落伍,因为涉及到专利,也不好说太多。

Puppet运行脚本失败

puppet运行一个shell的脚本,如果是puppet的agent定期执行的,就是不成功,但是puppet agent -t运行就可以,开始以为是用户身份的问题,加了调试命令打出来的用户身份没有问题,脚本里面原来也有reboot也是不好使,但是加了sudo在前面就解决,就在那个命令前面也加了sudo,还是不好使,改成su再执行,依然不行,百思不得其解。

后来灵光一现,打印了命令行执行时的env,然后在脚本里面也把env输出了出来,通过puppet的service跑的时候果然env里面少了很多东西,仔细想想也了然,因为puppet的service的启动顺序是早于系统的那个profile的初始化的,所以很多环境变量没有被设置。

把在控制台直接跑的时候的env的结果保存下来并在脚本里面import进去再运行,果然没有问题。

这个很妖异的问题就这么解决了,命令行直接执行脚本以及puppet agent -t直接运行都没有问题,但是puppet的service自动触发的就是不行,源于service的启动早于系统的完全初始化。

版本陷阱

前段时间接手了系统的升级功能,看了安装和升级的部分,关于版本的处理简直不能直视,因为全部是hard code的,每次版本有任何修改都需要修改脚本,我接手后重写了升级部分,但是没有想到最后还是栽在了版本问题上,因为我调用了一个系统原有的升级脚本,而那个脚本需要传入包的版本号,所以第一个升级包中我也hard code了那个包的版本号,谁想GA的前一天友队升级了那个包,我们的Build工程师更新了那个包,改了相关的脚本但是没有更新升级部分,更大的集成的时候就出问题了。。。真的是怕什么来什么。

intersect的性能问题

我们有张表是存储用户自定义的类似tag的信息的,有一个功能是按照tag进行搜索,而且支持搜索多个tag查找同时使用这些tag的对象,最开始的实现就是使用的intersect,我感觉可能有问题,然后正好没有太多的事情,就试了下性能,发现那个SQL可以进行改造,变成group by 加 having的模式,一个查询搞定,弄了大概4万条数据,两个SQL(同时查4个Tag)的对比结果显示,前面的SQL会扫描整个表4次(和查询的tag的次数直接相关),并且有一次写入操作,而后面的只有一次扫描没有写入操作,时间上后面的SQL的性能是前者的两倍以上。所以对于同质的SQL的intersect可以转换为这样的group by加having的模式。

原来的SQL:

select ObjectID from ConfigObjectMetaData where KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 6769857814803370866 and ValueInt32 = 2 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 3984357063977881949 and ValueInt32 = 3 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160 and ObjectType = 10

修改后的:
select ObjectID from ConfigObjectMetaData where ObjectType = 10 and (
(KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705)
or
(KeyNameHash = 6769857814803370866 and ValueInt32 = 2)
or
(KeyNameHash = 3984357063977881949 and ValueInt32 = 3)
or
(KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160)
)
group by ObjectID
having count(ObjectID)=4

Windows下的文件定期备份

应该说这个是简单得不能再简单的事情了,但是在Windows下也不是很容易,主要是OS没有现成的工具,而自带的DOS命令又稍显弱了一点,稍微使用点技巧还是可以解决的。

既然是备份,当然备份到其它的物理机最好,所以第一步就是使用Windows的网络磁盘功能,把其它物理机的具有可写权限的目录映射到本地的磁盘,默认第一个应该是磁盘Z:

然后就是写一个批处理文件完成目录创建和文件拷贝,目录名是当前日期:

Z:
cd targetSubDir
set dirname=%date:~10,4%-%date:~4,2%-%date:~7,2%
mkdir %dirname%
cd %dirname%
copy originalDir\*.* .

简单的说一下,第二行就是进到子目录,如果你备份到本来就是映射盘的根目录,第二行就不用了。第三行是生成当前日期,%DATE%本来就是当前日期,但是格式里面包含空格和/,因此不是合法的目录名,我们把它转换为YYYY-MM-DD这样的合法目录名格式,需要说明的是,网上有文章说不同的OS的默认日期格式不一样,语言不同应该也不一样,我试的是2003Server版,英文。然后创建这个目录,进入这个目录,然后从本地的目录拷贝内容,如果需要备份的内容还包含目录结构,就把copy换成xcopy,originalDir就是本地的需要备份的内容的路径,最好是完整路径,例如c:\db。

第三步就是建一个Schedule Task,是每天跑还是每周或者每月就看自己的需求了,这个很简单,不多说。

超短的Iteration

项目正式启动,但是时间很紧,两个月时间要把对旧系统的修改做好,因为要赶他们的一个发布计划。两个月被划分成3个Iteration,扣除前期的讨论时间和预留的时间,实际就剩6周,所以一个Iteration就是两周,上周计划开始的时候还在讨论设计,不过这个也怪我,因为在Iteration开始的前一周的周三抛出一个我的设计想法,和中国这边的团队讨论了两天,周五才发邮件给美国的同事,到了周二才正式开会确定采用我的设计,不过架构师要求快速出个原型,还好比较顺利,我的设计还是蛮符合预期的,很多地方甚至比预期的还顺利,根本不用修改代码直接就是OK的。不过,实际上,我们上周还没有把Code Base准备好,开发环境也没有准备好,周五的时候匆忙把Code Base弄好了,下周我还得把我负责的基础类弄好,还有新进的设备得弄好。好多事情啊。估计这个Iteration的BurnDown Chart会很难看,因为上周一周基本上都在做计划外的事情。

更早的文章

© 2020 解惑

本主题由Anders Noren提供向上 ↑