迁移Jira的数据库到Mysql

前言

买了Jira Software Server自用也有一段时间了,之前安装的时候为了图省事,采用了内置的H2数据库,用了这么久,一直提醒我作为生产环境需要换成Mysql数据库,终于闲下来可以换一下。

开工

按照官方的步骤

1、首先备份数据。这个很简单,在后台就可以备份。

2、然后安装Mysql的JDBC驱动

To copy the MySQL JDBC driver to your application server:

Get the MySQL driver:
If you are installing Jira, download the recommended MySQL driver JDBC Connector/J 5.1 from https://dev.mysql.com/downloads/connector/j/ 
You can download either the .tar.gz or the .zip file by selecting the 'Platform Independent' option. Extract the jar for the driver (e.g. mysql-connector-java-5.x.x-bin.jar) from the archive.

Restart Jira / Jira service.

这里遇到了一个问题,Mysql官方下载地址 https://dev.mysql.com/downloads/connector/j/ 进去以后下载到的是Connector/J 8.0.11,而这个版本是不能在JIRA使用的,会报错。
这里一定要点Looking for previous GA versions下载老版本,我用的是5.1.46终于可以正常使用。
安装完毕后重启JIRA

3、使用官方配置工具迁移

Using the Jira configuration tool — Use this method, if you have an existing Jira instance. Your settings will be saved to the dbconfig.xml file in your Jira home directory.

这个工具默认是在/opt/atlassian/jira/里的,但是当我打开运行的时候产生了报错,说我JAVA版本不对,可是我明明JIRA都可以运行,怎么到了你这里连个工具都运行不了了呢。
查了一下资料原来是openJDK是不认的,必须是官方OracleJDK才行,因为这两个JDK的version输出不一样,要么改tools代码,要么换个JDK。我选择换JDK,毕竟OpenJDK后面还不知道有啥坑,还是用Oracle官方的吧。

使用工具一步步配置好数据库连接以后,启动Jira,遇到了无限500报错。看logs文件夹里的日志,应该是数据库连接成功,但是库名不对。检查了几遍明明是对的,看了一下连接,好像连的是一个不存在的名为PUBLIC的库。又用配置工具配置了几次,依旧不行。
查资料得知配置文件修改的是dbconfig.xml文件。这个文件在/var/atlassian/application-data/jira目录下。赶紧去看了一下。里面有一个莫名其妙的 <schema-name>PUBLIC</schema-name> 字段,查遍了官方说明,都没看到有写这个字段。试着把这个字段改成正确的数据库名称,重启Jira,居然可以正常使用了。

4、然后就是进入初始化安装流程,这里选择导入已有数据,然后输入备份数据位置,等待即可。

总结

整个迁移过程说简单也简单,说坑也挺坑的,主要有这么几个点:

1、对Java的SDK对版本和类型(OpenJDK、OracleJDK)有奇怪要求。
2、对Mysql connector版本有奇怪要求,8不行5.1.46可以
3、官方配置工具配置完以后数据库居然不对,需要手动去配置文件里面修改。而这个dbconfig.xml配置文件又找了好久。
4、全都搞完以后日志里有一堆关于mysql连接不是ssl的Warning,害得我又去dbconfig.xml里把连接串url里加了个useSSL=false才正常。

终于可以正常用Jira Software了。这里强烈推荐一下这个管理工具,不管是做团队的项目管理,还是个人的事务管理,都肥肠好用哦。

年轻人的第一个AWS Lambda函数

  • 前言

之前用Go写的VSCO接口失效了,下午又用Python重新写了一个。因为VSCO的锁区,导致在香港的服务器无法获取到需要的json,而美国服务器延迟又略大,又不想专门为这个API开一台服务器用,这时候突然想到了AWS的Lambda函数。

AWS Lambda介绍我就直接复制 https://aws.amazon.com/cn/documentation/lambda/

使用 AWS Lambda,您无需预置或管理服务器即可运行代码。您只需为使用的计算时间付费,在代码未运行期间不产生任何费用。您可以为几乎任何类型的应用程序或后端服务运行代码,而无需任何管理。只需上传您的代码,Lambda会处理运行和扩展高可用性代码所需的一切工作。您可以将您的代码设置为自动从其他 AWS 服务触发,或者直接从任何 Web 或移动应用程序调用。

而从公网调用这个函数,又需要Amazon API Gateway https://aws.amazon.com/cn/documentation/apigateway/

Amazon API Gateway 是一种完全托管型服务,使开发人员可以轻松发布、维护、监控和保护任何规模的 API。创建 API 以从后端服务(比如 Amazon Elastic Compute Cloud (Amazon EC2) 上运行的应用程序、AWS Lambda 上运行的代码或者任何 Web 应用程序)访问数据、业务逻辑或功能。可将 API Gateway 视为云中的一个背板,用于连接 AWS 服务和其他公有或私有网站。它可以提供一致的 RESTful 应用程序编程接口 (API),让移动和 Web 应用程序可以访问 AWS 服务。

这样看下来,我把Lambda函数写好,使用API Gateway来控制访问,整体下来就是一个无服务器应用程序的demo了。

API Gateway 与 AWS Lambda 共同构成 AWS 无服务器基础设施中面向应用程序的部分。对于调用公开 AWS 服务的应用程序,您可以使用 Lambda 与所需的服务交互,并通过 API Gateway 中的 API 方法来使用 Lambda 函数。AWS Lambda 在高可用性计算基础设施上运行代码。它会进行必要的计算资源执行和管理工作。为了支持无服务器应用程序,API Gateway 可以支持与 AWS Lambda 的简化代理集成和 HTTP 终端节点。

  • 实践

为了访问速度,这里我选择AWS的东京区域,首先创建一个Lambda函数,当前支持C#,Go,JAVA,Nodejs,Python几种语言的不同版本,足够日常使用了,这里我选择Python,并且把代码上传到AWS,注意配置好主函数(您函数中的 filename.handler-method 值。例如:“main.handler” 将调用在 main.py 中定义的处理程序方法。)

左边添加一个触发器,这里采用API Gateway,配置好方法请求等参数,这里需要注意的是在API Gateway管理界面需要配置好各种请求和相应阶段以后可以进行测试,并且需要部署API,而部署完以后的API是有Stage的,URL里也需要注意有Stage,否则会报 {"message":"Missing Authentication Token"} 错误。

绑定自定义域名aws-apne-gateway.tms.im,这里需要先在ACM(Amazon Certificate Manager)里导入或者生成域名证书。

这样就完成了一个Lambda函数的部署,整体操作下来还是很简单顺畅的。

  • 总结

一直想体验一下AWS的FaaS架构,今天也是借着这个小需求的机会体验了一把FaaS,感觉是开发者的福音,完全不需要考虑后端服务器的环境,部署等各种问题,只需要关注核心逻辑实现,把函数当成一个简单的黑盒实现即可。
缺点嘛也很明显,只适合不是那么复杂的可以拆分出来的函数逻辑的实现,和微服务架构有点像,如果业务逻辑很重并且非常缠绕,互相依赖太严重,无法通过拆分成小函数来执行的话可能就不太适合FaaS架构了。

nginx模块开发遇到的一个坑

先说总结:ngx_rbtree在不同worker进程相互独立。

然后是过程:

今天因为一个nginx模块开发的时候,不同fd进来使用ngx_find_value在红黑树ngx_rbtree里找不到上一个fd设置的值的情况,调试了一下午。

突然想起来nginx是多进程模式,有一个worker_processes参数。而模块又是worker进程分别调用,同样红黑树也是不同worker进程维护自己的红黑树。

怪不得接入不同worker的fd在红黑树中设置的值相互查不到。

高并发应对

最近看了好多高并发的文章和讨论。随便写写。
对于高并发的解决应对方案,无非是以下几点:

  • 首先是对业务逻辑的解析。看哪些是可以进行高并发优化的。有些业务是可以上Cache的,有一些静态是可以上CDN的。还有一些是可以通过中间层和持久连接解决的。不同的业务有不同的优化方案。对业务逻辑的透彻解析是高并发应对的最基础也是最重要的部分。
  • 其次是针对不同的业务逻辑进行不同的方案选择。技术上面无非是动静态分离,CDN,请求队列,拉取变推送,缓存共享,负载均衡,数据分库分表,数据库缓存,读写分离等技术,一般会用到其中的一种或多种搭配使用。往大方向说一般通用的解决方案就是首先动静态内容分离,静态资源上CDN,动态请求回源,源服务器做负载均衡,把请求进行队列化,源服务器缓存共享,持久连接,数据库前加cache,数据库中间层统一处理,对后端多台数据库做读写分离,分库分表处理。
  • 还要考虑系统设计要尽可能的方便水平扩展,任何环节当前机器数量扛不住的情况下可以方便的增加机器。当然在向可水平扩展的架构转化过程中会有一定性能损失,这就要具体情况具体分析权衡好哪些环节进行转化。

其他的想到再写。

采用ELK搭建nginx日志分析平台

ELK=Elasticsearch(数据库)+Logstash(Log收集处理)+Kibana(展示平台)
对于这几个软件的特性和优势在这里就不再赘述了。可以参考各种资料和说明。
以前一直觉得ELK做日志收集分析有点太重量级,占用资源过大。最近对Elasticsearch进行了一些了解,感觉有很多优秀的特性值得采用。于是重新开始安装这套经典的重量级的开源日志收集分析平台。

对于ELK的安装在官网都有下载
这里只说几个要注意的地方
1、E和L需要JAVA环境,而且对版本号有依赖。
2、Elasticsearch不能以root权限运行。请自行建立非root账户
3、Kibana的rpm包安装完以后在/opt目录下。
4、Elasticsearch想创建pid文件运行(我用monit做监控用)请自行-f /tmp/es.pid
5、Logstash的配置文件需要自行建立 运行命令是 Logstash agent -f 配置文件路径

下面着重讲一下如何用Logstash对nginx的日志文件进行处理和入库Elasticsearch

首先在nginx的配置文件里对log-format进行配置
log_format access '$http_host $server_addr $remote_addr [$time_local] "$request" ' '$request_body $status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time';
这里包含 访问域名、服务器IP、来源IP、时间(带时区)、请求动词、请求体、返回值、请求体字节数、来源referer、用户UA、请求时间、后端处理时间(PHP处理时间)

tms.im 10.70.29.98 58.21.16.54 [26/Jun/2016:16:39:28 +0800] “GET /favicon.png HTTP/1.1” - 404 191 “http://tms.im/index.php” “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36” 0.000 -

以上是log示例,因为是静态文件 所以后端处理返回时间是0
新建一个logstash的配置文件nginx.conf

input {
   file {
     type => "nginx-access"
     path => "/data/wwwlogs/access_nginx.log"
   }
}
filter {
   grok {
        match => {
            "message"=>"%{IPORHOST:domain} %{IP:route_ip} %{IP:real_ip} \[%{HTTPDATE:timestamp}\] \"%    {WORD:http_verb} %{URIPATH:baseurl}(?:\?%{NOTSPACE:request}|) HTTP/%{NUMBER:http_version}\" (?:-|%    {NOTSPACE:request}) %{NUMBER:http_status_code} (?:%{NUMBER:bytes_read}|-) %{QS:referrer} %{QS:agent} %    {NUMBER:time_duration:float} (?:%{NUMBER:time_backend_response:float}|-)"
        }
    }
}
output {
 elasticsearch {
    hosts => "127.0.0.1"
  }
}

其中需要注意的是grok的match段,网上查到的资料大都是直接输入grok表达式,而这种匹配已经被弃用,请使用如上的match段进行grok匹配。

这里grok匹配推荐一个网站可以在线进行grok表达式测试
http://grokdebug.herokuapp.com/
然后启动Logstash(之前已经启动了elasticsearch和kibana)

/ELK/logstash/bin/logstash -f /ELK/logstash/nginx.conf

这样Logstash就配置完成了。进入kibana的管理界面。第一次进入需要进行mapping,点确定完成后即可看到数据。
效果
然后就可以建立Dashboard做各种统计分析了。
效果