分类: 编程

  • 配置中心之Apollo

    随着业务系统越来越复杂,微服务架构成为主流。管理众多微服务的配置是一件头疼的事。在Spring Cloud中有提供配置中心模块,是基于文件管理方式,依赖svn/git,修改配置文件后无法自动同步。

    Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

    与Spring Cloud相比,Apollo是将配置文件存入MySQL数据库中,有WEB管理界面,有权限控制,支持灰度发布,配置回滚及集群和配置文件时实同步。同时也能很好的与Spring Boot、Spring Cloud整合。以下是它的基础模型和架构模块图。

    关于Apollo详细设计可参与官方文档:Apollo配置中心设计

    Apollo的官方资料写得挺详细,但文档的结构不太符合我的阅读习惯。比如:在介绍一项配置,它列出各种集成方式。我觉得应该分开,基础的,与Spring Boot集成的,与Spring Cloud集成。废话不多说,以下是我的操作回放。

    (更多…)
  • 本地架设私有git服务器

    从事软件开发肯定少不了对代码进行管理和版本控制。以前一直使用svn,好处是简单又有权限控制。后来项目种类多了,用git管理,不相关的项目做隔离。使用git有很多种方式,自己管理代码采用ssh连接,方便快捷。现在希望有一个好的呈现界面,像github和gitlab一样,方便查阅和分享。

    github属于微软派系,自己用的比较多,可惜不提供源码自己架设。所以我选择google旗下的gitlab。
    本地环境:Ubuntu Server 18.04

    我采用docker安装,首先安装docker
    apt install docker-compose

    下载gitlab社区版镜像
    docker pull gitlab/gitlab-ce

    启动gitlab

    docker run –detach –hostname gitlab.wangzhengzhen.com –publish 10080:80 –publish 10022:22 –name gitlab –restart always –volume /home/docker/gitlab/config:/etc/gitlab –volume /home/docker/gitlab/logs:/var/log/gitlab –volume /home/docker/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:latest

    在这里,端口和目录的映射跟据自己需要修改。
    PS:启动过程有点慢,需要耐心等待。

    (更多…)
  • 实现 MySQL Top 函数【原创】

    需求:查询数据,根据字段分组,取出分组后每组的前N条记录。
    如果是在SQL Server中,可以使用top,取前N条记录。但是在MySQL是不支持的。网上说的比较多的是用limit N,虽然可以取到前N条,但那是分组后的N条,不是每组N条数据,所以不符合需求,排除。还有一种是使用union把多个结果连接起来,这种方法需要提前知道有分多少组,而且不适合分组太多的场景,排除。

    我的实现思路:
    1.查出分组后的数据。
    2.使用原表数据和分组后的数据连接起来。
    3.按组生成序列(从0开始)。
    4.根据序列编号做为条件,找出前N条数据。
    (更多…)

  • 从SQL查询结果随机取一条数据

    最近工作中会涉及复杂的SQL语句,还是挺有意思的。以前想写没有应用场景,现在正好可以多锻炼锻炼。我觉得在实际开发中,程序代码并不是最难的,最难的还是SQL。SQL逻辑性最强,而且还要很清楚表设计,业务场景。特别是复杂的业条场景下提炼数据,要考虑到功能,性能,是否会锁表。
    需求:有一张表保存诺干条广告信息。当APP启动时,根据登录用户所在的区域,随机取出一条广告返回,作为启动页。

    数据库:MySQL
    刚开始,我的做法是:

    select floor(max(startPageId) * rand()) from ghome.ghome_startpage_info where 1=1 and status!='00';
    

    startPageId是自动增长的Integer型
    其他where条件不贴出来了。这句意思是,查询符合条件的数据,根据 max 函数找出结果最大的,乘以 rand 函数随机生成的一个小于1的数,再用 floor 去掉小数位。得出一个 randId。
    (更多…)

  • [原创]通用验证工具2.0

    两年前,我在这里发布了”JAVA通用验证工具”,并开源共享到 github 上。在之后的项目中,也是有使用的,算得上是经历了线上的考验。与其他如:Spring Validator,Apache Validator相比,主要有几个优点:
    1.无第三方依懒引入,更轻量更容易扩展。
    2.对于JAVA对象支持分组,根据不同业务场景验证必要字段。
    3.对Android提供独立支持,验证返回资源引用ID。
    (更多…)

  • 云开发IDE - Eclipse Che

    Eclipse Che是一个现代的、开放源代码的软件开发环境,它是基于云端的IDE。官方没有提供直接可运行的程序,而是使用现在正火的Docker镜像。官方推荐Docker 17+,首先需把本的Docker升级到最新。

    不同平台的升级方法:https://docs.docker.com/install/
    我本地的环境是Ubuntu 18.04,使用单用户安装方式。执行如下:

    1.卸载旧的docker

    apt remove docker docker-engine docker.io
    

    2.安装必要的软件包

    apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        software-properties-common
    

    (更多…)

  • Android使用SOAP调用远程服务

    SOAP是一种基于XML的协议规范,最近正好使用到了它。在Android中,可以使用KSOAP2来调用WebService。
    KSOAP2相关文档:http://simpligility.github.io/ksoap2-android/
    KSOAP2下载地址:https://oss.sonatype.org/content/repositories/ksoap2-android-releases/
    下载 ksoap2-android-assembly-3.6.0-jar-with-dependencies.jar,将该jar包放入工程的libs目录中。调用步聚如下:

    SoapObject request = new SoapObject("http://service", "getName");
    

    SoapObject类的第1个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。第2个参数表示要调用的WebService方法名。
    设置调用方法的参数值,这一步是可选的,如果方法没有参数,可以省略这一步。设置方法的参数值的代码如下:
    (更多…)

  • 解析HTTP协议实现文件上传

    在J2EE开发中,使用浏览器上传文件很简单,服务器用Apache的Commons FileUpload实现就可以了。但是在开发C/S架构的程序时就需要自己处理。用代码实现文件上传需要对表单的multipart/form-data有所了解,(表单默认情况下使用application/x-www-form-urlencoded)。

    在multipart/form-data中Content-Type是这样的:

    boundary是表示分隔,用于分隔多个文件。格式是 — 后面可以跟随一串随机数。
    (更多…)

  • Android 图片压缩

    现在的手机动不动就是几千万像素,拍下来的照片一般都有3M-5M,像华为荣耀7拍的有7M左右。这么大的图片上传不仅很慢,还会造成服务器端有很大的压力,所以有必要把图片进行压缩。

    压缩图片有两个要点:
    1.等比缩小图片大小
    2.适当降低图片质量
    现在的项目中需要有一个证件上传功能,在保证证件照清晰可辩的情况下要缩减图片大小,所以我写了一个工具类。
    (更多…)

  • J2EE基础框架集成

    Spring 4出来很长一段时间了,现在最新稳定版是4.2.4。我把外面做项目常用的框架集成写了一个demo,从请求到保存数据。可以作为项目快速搭建与开发。如果要提高效率和形成团队规范,还需要深度开发。
    项目为Maven工程,始用Eclipse创建。导入项目后可能需要一段时间让Eclipse自动下载依赖包。依赖包主要有:Spring、Spring Web、Spring Jdbc、MyBatis、Mybatis Spring、MySQL Connect Java、Apache Common DBCP2、Log4j2。

    项目结构如下:
    20151220132534
    数据库脚本:
    (更多…)

  • openssl生成pfx证书

    做为一个javaer,生成证书工作理应首选keytool。但是keytool生成的证书是jsk的keystore,不符合要求,只有使用openssl了。
    openssl是一个很强大的工具,里面有很多加密算法和证书格式,对此我也只是了解一部分,有时间要好好补补这一块知识。以前在接支付宝时使用openssl生成过pfx证书,没有记住命令。在网上一搜,大部分都是5部生成https证书的。好不容易生成出来,特意mark一下。

    1.生成2048位的rsa私密。之所以使用2048是因为1024位的密钥对于现在计算机性能来说,比较容易破解。

    2.生成公钥,有需要的话可以不加上 -days参数。这个参数表示有效时间,单位是天。

    (更多…)

  • WebView控件加载银联WAP

    2015-06-15 17-26-46 的屏幕截图
    今天有个商户在测试环境遇到WebView控件无法加载银联wap的问题。具体他们怎么设置的就不清楚了,说了半天没说通,干脆自己写了个demo丢给他。
    WebView加载银联wap只需要注意两个问题:
    1.开启WebView控件的JS功能。
    2.因为测试环境下的https证书是不受任信的,所以需要做证书信任处理。
    核心代码如下:
    (更多…)

  • 端口批量转发工具v1.1

    之前因为工作需求,开发了一款端口转发工具,实现原理参见:JAVA实现端口转发功能。这段程序只能针对一个端口转发,要实现多个转发功能就需要运行多个程序,所以便开发了新的增强版端口转发工具。

    新版端口批量转发工具的配置文件是参考另一款转发工具 (rinetd) 的格式来实现的,完全可以和rinetd配置文件共用。使用格式如下:

    listenIP listenPort destinationIP destinationPort
    参数说明:
    listenIP:本地监听网卡地址,输入0.0.0.0接受所有连接
    listenPort:本地监听端口
    destinationIP:转发目标地址
    destinationPort:转发目标端口

    (更多…)

  • JAVA实现端口转发功能

    使用vmware workstation发现NAT模式端口转发存在一些问题。

    1.在windows系统下虚拟XP,在XP中使用VPN,然后用ccproxy架设代理。虚拟xp使用的是NAT模式连网,使用vmware workstation自带的端口转发工具设置808端口转发(ccproxy代理端口)不能上网。

    2.在centos系统下vmware workstation的网络工具中,没有NAT端口转发选项。手动更改配置文件实现端口转发失败。

    其实我要的功能很简单,就一个端口转发。在B机器上安装好虚拟机C,用A机器去连接。因为B机器和A机器是不同网段且不相通(但是A能连接B),所以A连接C需要B转发。使用vmware workstation自带转发实现不了,于是自己写了一个端口转发的小程序。是使用JAVA编写的,能运行于全平台。

    (更多…)

  • JS分页插件

    查询分页几乎是每个系统都会用到的,之前用JSP写了一个分页组件,但是使用起来不太访便,需要在导入分页组件的页面上重写一个javascript的查询方法。所以我进行了改进,用纯javascript实现,写了一个新的分页插件。这个版本的分页插件不仅必免重写查询方法,还增强了通用性。因为是javascript实现,所以除了适用于java,也适用于php、.net等。其实这个分页插件是13年上半年就写好了的,一直在使用,没有发现bug。

    使用时需要引入jquery和分页插件本身js文件。

    <script src="./jquery.js" type="text/javascript">
    <script src="./paging.js" type="text/javascript"></script>
    <script type="text/javascript">
    var paging = $.paging({
                   id:"paging",
                   current:"${paging.current }",
                   row:"${paging.row }",
                   count:"${paging.count}",
                   total:"${paging.total}",
                   url:queryUrl,
                   condition:{}
                   });
    </script>

    (更多…)