微服务项目运维管理


1 从运维角度看微服务

1.1 单体应用vs微服务

1 单体架构优势

(1) 易于部署

(2) 易于测试

 

2 单体架构不足

(1) 代码膨胀、难以维护

(2) 构建、部署成本大

(3) 新人上手难

1.2 微服务特点

1、服务组件化

每个服务独立开发、部署、有效避免一个服务的修改引起整个系统重新部署。

 

2 技术栈灵活

约定通信方式,使得服务本身功能实现对技术要求不再那么的敏感。

 

3 独立部署

每个微服务独立部署,加快部署速度,方便扩展。

 

4 扩展性强

每个微服务可以部署多个,并且有负载均衡能力。

 

5 独立数据

每个微服务有独立的基本组件,例如数据库、缓存等。

1.3 微服务不足

1 沟通成本

2 数据一致性

3 运维成本

4 内部架构复杂性

5 大量服务如何治理

6 如何部署

7 如何监控

8 内部数据流复杂,事务不易管理

1.4 java微服务框架

1java在开发语言排行榜第一,在微服务实现这块也是最为成熟的、应用广泛。

2java微服务框架介绍

(1) Spring Boot

快速开发微服务的框架。

(2) Spring Cloud

基于Spring Boot实现的一个完整的微服务解决方案。

(3) Dubbo

阿里巴巴开源的微服务治理框架。

2 部署微服务考虑的问题

2.1 微服务架构图

wps1 

(1) 微服务间如何通信

(2) 微服务如何发现彼此

(3) 组件之间怎么调用关系

注册中心

(4) 哪个服务作为整个网站入口

(5) 哪些微服务需要对外访问

portal

(6) 微服务怎么部署?更新?扩容?

jenkins ansiable

2.2 为什么要用注册中心

1 微服务面向的问题

(1) 怎么记录一个微服务多个副本接口地址

(2) 怎么实现一个微服务多个副本负载均衡

(3) 怎么判断一个微服务副本是否可用

(4) 主流注册中心EurekaNacosConsul

wps2 

3 部署SpringCloud微服务项目

3.1 熟悉SpringCloud微服务项目

1 项目架构图

wps3 

 

2 项目信息表

服务器IP

主机名

端口

服务

用途

172.16.1.61

172.16.1.62

172.16.1.63

eureka01

eureka02

eureka03

 

8888

 

eureka

 

注册中心

172.16.1.64

mariadb

3306

mariadb

数据库

 

172.16.1.65

172.16.1.66

 

ms01

ms02

8010

product

商品服务

8020

order

订单服务

8030

stock

库存服务

8080

portal

前端

9999

gateway

网关

172.16.1.67

nginx

80

nginx

负载均衡器

172.16.1.68

msjenkins

8080

jenkins

微服务发布平台

172.16.1.69

msgitlab

80

gitlab

代码仓库

172.16.1.70

pinpoint

8079

pinpoint相关组件

微服务监控系统

3 环境准备

(1) 172.16.1.61机器上安装mavenjdk环境

1) 配置环境变量

# tar -xzf jdk-8u45-linux-x64.tar.gz

# tar -xzf apache-maven-3.5.0-bin.tar.gz

# mv jdk1.8.0_45/ /usr/local/jdk

# mv apache-maven-3.5.0/ /usr/local/maven

# cat >>/etc/profile<< EOF

export JAVA_HOME=/usr/local/jdk

export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/rt.jar

export PATH=$JAVA_HOME/bin:/usr/local/maven/bin:$PATH

EOF

# source /etc/profile

 

2) 修改maven仓库地址

参考网址:https://maven.aliyun.com/mvn/guide

打开maven的配置文件,一般在maven安装目录的conf/settings.xml,在<mirrors></mirrors>标签中添加如下mirror子节点。

# vim /usr/local/maven/conf/settings.xml

<mirror>

  <id>aliyunmaven</id>

  <mirrorOf>*</mirrorOf>

  <name>阿里云公共仓库</name>

  <url>https://maven.aliyun.com/repository/public</url>

</mirror>

 

(2) 172.16.1.62172.16.1.63172.16.1.65172.16.1.66机器上安装jdk环境

# tar -xzf jdk-8u45-linux-x64.tar.gz

# mv jdk1.8.0_45/ /usr/local/jdk

# cat >>/etc/profile<< EOF

export JAVA_HOME=/usr/local/jdk

export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/rt.jar

export PATH=$JAVA_HOME/bin:$PATH

EOF

# source /etc/profile

3.2 源代码编译构建

172.16.1.61节点上操作

1 编译

# unzip simple-microservice.zip

# cd simple-microservice/

# mvn clean package -Dmaven.test.skip=true

wps4 

 

2 编译后jar包所在位置

(1) 服务目录

wps5 

(2) 配置目录

wps6 

3.3 部署Eureka集群

172.16.1.616263节点上操作

1 修改源代码中eureka配置文件并编译

172.16.1.61节点上操作

# vim eureka-service/src/main/resources/application-fat.yml

eureka:

  server:

    renewal-percent-threshold: 0.9

    enable-self-preservation: false

    eviction-interval-timer-in-ms: 40000

  instance:

    hostname: 127.0.0.1

    prefer-ip-address: true

  client:

    register-with-eureka: true

    serviceUrl:

      defaultZone: http://172.16.1.61:${server.port}/eureka/,http://172.16.1.62:${server.port}/eureka/,http://172.16.1.63:${server.port}/eureka/

fetch-registry: true

 

编译eureka

# mvn clean package -Dmaven.test.skip=true

 

2 将编译好的jar包放到指定目录下

# mkdir -p /data/ms/eureka

# cp -a eureka-service/target/eureka-service.jar /data/ms/eureka/

 

3 使用systemd管理eureka

# vim /usr/lib/systemd/system/eureka.service

[Unit]

Description=Eureka

Documentation=eureka

[Service]

ExecStart=/usr/local/jdk/bin/java -jar /data/ms/eureka/eureka-service.jar

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl start eureka.service

# systemctl enable eureka.service

# netstat -tunlp | grep 8888

tcp6       0      0 :::8888                 :::*                    LISTEN      2734/java          

# jps -l

2865 sun.tools.jps.Jps

2734 /data/ms/eureka/eureka-service.jar

 

4 在浏览器中访问

# http://172.16.1.61:8888/

wps7 

3.4 部署mysql数据库

172.16.1.64节点上操作

1 安装Mariadb数据库

# yum install mariadb-server -y

# systemctl start mariadb

# systemctl enable mariadb

# mysqladmin -uroot password '123456'

# mysql -uroot -p123456

 

2 创建一个账号并授权,该账户用于微服务连接

MariaDB [(none)]> grant all on *.* to 'ms'@'%' identified by '123456';

MariaDB [(none)]> flush privileges;

 

3 将源代码目录里sql文件拷贝到数据库服务器上

172.16.1.61节点上操作

# scp -r db/ root@172.16.1.64:~

 

4 创建数据库并导入表

MariaDB [(none)]> create database tb_product;

MariaDB [(none)]> create database tb_stock;

MariaDB [(none)]> create database tb_order;

 

MariaDB [(none)]> use tb_product;

MariaDB [tb_product]> source /root/db/product.sql

MariaDB [tb_product]> use tb_stock;

MariaDB [tb_stock]> source /root/db/stock.sql

MariaDB [tb_stock]> use tb_order;

MariaDB [tb_order]> source /root/db/order.sql

MariaDB [tb_order]> exit;

3.5 部署业务程序、网关、前端

1 172.16.1.6566节点上创建微服务目录

# mkdir -p /data/ms/{product,stock,order,portal,gateway}

 

2 修改源码配置文件并编译

172.16.1.61节点上操作

(1) 业务程序

修改商品服务配置文件如下,库存服务、订单服务配置修改同理

# cat product-service/product-service-biz/src/main/resources/application-fat.yml

spring:

  datasource:

    url: jdbc:mysql://172.16.1.64:3306/tb_product?characterEncoding=utf-8

    username: ms

    password: 123456

    driver-class-name: com.mysql.jdbc.Driver

 

eureka:

  instance:

    prefer-ip-address: true

  client:

    register-with-eureka: true

    fetch-registry: true

    service-url:

      defaultZone: http://172.16.1.61:8888/eureka/,http://172.16.1.62:8888/eureka/,http://172.16.1.63:8888/eureka/

 

(2) 前端、网关

修改前端服务配置文件如下、网关服务修改配置文件同理

# cat portal-service/src/main/resources/application-fat.yml

eureka:

  instance:

    prefer-ip-address: true

  client:

    service-url:

      defaultZone: http://172.16.1.61:8888/eureka/,http://172.16.1.62:8888/eureka/,http://172.16.1.63:8888/eureka/

    register-with-eureka: true

    fetch-registry: true

 

spring:

  freemarker:

    allow-request-override: false

    allow-session-override: false

    cache: true

    charset: UTF-8

    check-template-location: true

    content-type: text/html

    enabled: true

    expose-request-attributes: false

    expose-session-attributes: false

    expose-spring-macro-helpers: true

    prefer-file-system-access: true

    suffix: .ftl

template-loader-path: classpath:/templates/

 

(3) 编译

# mvn clean package -Dmaven.test.skip=true

 

3 编写脚本拷贝编译好的jar包到172.16.1.6566机器上

172.16.1.61节点上操作

(1) 创建172.16.1.61节点和172.16.1.6566节点的免交互

# ssh-keygen

# ssh-copy-id root@172.16.1.65

# ssh-copy-id root@172.16.1.66

 

(2) 业务程序

for ip in 172.16.1.65 172.16.1.66; do

for name in product order stock; do

    scp $name-service/$name-service-biz/target/$name-service-biz.jar root@$ip:/data/ms/$name

done

done

 

(3) 前端、网关

for ip in 172.16.1.65 172.16.1.66; do

for name in portal gateway; do

        scp $name-service/target/$name-service.jar root@$ip:/data/ms/$name

done

done

 

4 生成systemd service配置文件并启动服务

172.16.1.6566节点上操作

(1) 生成业务程序的systemd service

for name in product order stock; do

cat > /usr/lib/systemd/system/$name.service << EOF

[Unit]

Description=$name

Documentation=$name

[Service]

ExecStart=/usr/local/jdk/bin/java -jar /data/ms/$name/$name-service-biz.jar

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

EOF

done

 

(2) 生成前端、网关的systemd service

for name in portal gateway; do

cat > /usr/lib/systemd/system/$name.service << EOF

[Unit]

Description=$name

Documentation=$name

[Service]

ExecStart=/usr/local/jdk/bin/java -jar /data/ms/$name/$name-service.jar

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

EOF

done

 

(3) 启动业务程序、前端、网关,并加入到开机自启

for name in product order stock portal gateway; do

systemctl restart $name

systemctl enable $name

done

 

说明:如果服务没有起来,可以使用journalctl -u $name -f持续查看服务的日志信息。

 

(4) 查看java进程

# jps -l

3216 /data/ms/gateway/gateway-service.jar

3106 /data/ms/order/order-service-biz.jar

3076 /data/ms/product/product-service-biz.jar

3176 /data/ms/portal/portal-service.jar

3146 /data/ms/stock/stock-service-biz.jar

3434 sun.tools.jps.Jps

 

5 在浏览器中查看注册的业务程序、前端、网关

url: http://172.16.1.61:8888/

wps8 

3.6 使用Nginx负载均衡对外访问

wps9 

172.16.1.67节点上操作

 

1 安装nginx

# yum install nginx -y

 

2 配置nginx负载均衡文件

(1) 配置文件

# cat /etc/nginx/conf.d/ms.conf

upstream gateway {

  server 172.16.1.65:9999;

  server 172.16.1.66:9999;

}

 

server {

  listen 80;

  server_name gateway.ctnrs.com;

  access_log /var/log/nginx/gateway-access.log main;

  location / {

    proxy_pass http://gateway;

  }

}

 

upstream portal {

  server 172.16.1.65:8080;

  server 172.16.1.66:8080;

}

 

server {

  listen 80;

  server_name portal.ctnrs.com;

  access_log /var/log/nginx/portal-access.log main;

  location / {

    proxy_pass http://portal;

  }

}

 

# 说明

# gateway 包含在 portal

# ls portal-service/src/main/resources/static/js/

# index.js  jquery-1.8.2.min.js  layui  orderList.js  productList.js

# portal 调用

# http://gateway.ctnrs.com/product/queryAllProduct

# http://gateway.ctnrs.com/order/queryAllOrder

 

(2) 检查配置文件

# nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

 

(3) 启动nginx并加入开机自启动

# systemctl restart nginx

# systemctl enable nginx

 

3 修改本地hosts解析

C:WindowsSystem32driversetchosts

 

172.16.1.67 portal.ctnrs.com gateway.ctnrs.com

 

4 在浏览其中访问

URL地址:http://portal.ctnrs.com/

wps10 

 

wps11 

4 基于jenkins构建微服务发布平台

172.16.1.78节点上操作。

wps12 

4.1 安装gitlabjenkins

1 使用docker方式在172.16.1.68节点上安装jenkins具体安装请参考jenkins安装文档,这里安装步骤省略。

2 使用docker方式在172.16.1.69节点上安装gitlab,具体安装请参考gitlab安装文档,这里安装步骤省略。

将修改好配置文件的微服务项目上传到gitlab的自建仓库project/microserver.git中,需要将已经编译好的target目录jar文件删除,否则会导致微服务无法在eureka集群中注册(这里省略步骤)wps13

4.2 安装ansiable

# yum install ansible -y                                                                     # ssh-keygen

# ssh-copy-id root@172.16.1.65

# ssh-copy-id root@172.16.1.66

 

测试ansiable

# vim /etc/ansible/hosts

[webservers]

172.16.1.65

172.16.1.66

# ansible webservers -m ping

wps14 

4.3 安装jenkins分布式节点

1 创建从节点的工作目录

# mkdir -p /jenkins_home

 

2 创建从节点

wps15 

 

3 上线从节点

wps16 

 

# cd /jenkins_home/

# wget http://172.16.1.68:8080/jnlpJars/agent.jar

 

# nohup /usr/local/jdk/bin/java -jar agent.jar -jnlpUrl http://172.16.1.68:8080/computer/localhost/slave-agent.jnlp -s

ecret 3def841847662ecd2ed43460f671b59ac112189107b952bf3ab3832b48d2fe01 -workDir "/jenkins_home" &>agent.log &

 

4 上线完成

wps17 

4.4 安装jenkins插件

1 发布流程

(1) 自动拉取代码

(2) 代码编译

(3) 推送构建文件

(4) 部署构建文件,并重启服务

(5) 测试访问

 

2 安装插件如下

pipeline(pipeline脚本)git(git命令,用于拉取git仓库)git parameter(获取git仓库标签)extended choice parameter(多选框)ansible(批量化处理)

4.5 创建pipeline项目

wps18 

4.6 根据pipeline语法生成器生成需要的pipeline脚本

1 获取git仓库标签脚本

wps19 

parameters {

  gitParameter branch: '', branchFilter: '.*', defaultValue: '', description: '请选择要发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_TAG'

}

 

2 生成要发布的微服务多选框的脚本

wps20 

wps21 

parameters {

  extendedChoice description: '请选择要发布的微服务', multiSelectDelimiter: ',', name: 'Service', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'portal,gateway,product,stock,order', visibleItemCount: 5

}

 

3 生成要发布服务器组的脚本

wps22 

parameters {

  choice choices: ['webservers1', 'webservers2'], description: '请选择要发布的服务器组', name: 'Servers'

}

 

4 生成拉取gitlab代码仓库的脚本

wps23 

checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'a0c7bec9-230b-4b86-995b-ef162b4d5f42', url: 'http://172.16.1.69/project/microserver.git']]])

4.7 创建pipeline脚本

pipeline {

    agent {

       label "localhost"

    }

 

parameters {

  gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '请选择要发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'

   extendedChoice description: '请选择要发布的微服务', multiSelectDelimiter: ',', name: 'Service', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'portal,gateway,product,stock,order', visibleItemCount: 5

   choice choices: ['webservers1', 'webservers2'], description: '请选择要发布的服务器组', name: 'Servers'

}

 

    stages {

        stage('拉取代码') {

            steps {

                checkout([$class: 'GitSCM', branches: [[name: '$Branch']], extensions: [], userRemoteConfigs: [[credentialsId: 'a0c7bec9-230b-4b86-995b-ef162b4d5f42', url: 'http://172.16.1.69/project/microserver.git']]])

            }

        }

 

        stage('代码编译') {

            steps {

                sh '''

                    JAVA_HOME=/usr/local/jdk

                    PATH=$JAVA_HOME/bin:/usr/local/maven/bin:$PATH

                    mvn clean package -Dmaven.test.skip=true

                '''

            }

        }

 

        stage('部署') {

            steps {

                // 将用户选择的微服务的构建文件拷贝到临时目录,以便ansible统一推送

                // Service=portal,gateway,product,stock,order

                script {

                    def tmp_dir = "$WORKSPACE/tmp"

                    def services = "$Service".split(",")

                    sh """

                        [ -d $tmp_dir ] && rm -rf $tmp_dir

                mkdir -p $tmp_dir

                    """

                for(name in services) {

                sh """

                echo $name

                pwd

                ls

                cd $name-service

                if ls |grep biz &>/dev/null;then

                   cd $name-service-biz

                fi

                mv target/*.jar $tmp_dir

                ls $tmp_dir

                """

                }

                }

 

                // 生成主机清单文件和playbook

                sh """

cat > /jenkins_home/.hosts << EOF

[webservers1]

172.16.1.65

[webservers2]

172.16.1.66

EOF

cat > /jenkins_home/.playbook <<EOF

- hosts: $Servers

  gather_facts: no

  vars:

    workspace: $WORKSPACE

    work_dir: "/data/ms"

    service_name: $Service  # Service=portal,gateway,product,stock,order

  tasks:

  - name: 推送构建文件

    copy:

      src={{ item }}

      dest={{ work_dir }}/{{ item.split("/")[-1].split("-")[0] }}

    with_fileglob:

      - "{{ workspace }}/tmp/*.jar"

  - name: 重启服务

    systemd: name={{ item }} state=restarted

    loop: "{{ service_name.split(',') }}"

EOF

                """

 

                ansiblePlaybook(

                  playbook: "/jenkins_home/.playbook",

                  inventory: "/jenkins_home/.hosts",

                  credentialsId: ""

                )

            }

        }

    }

}

 

 

4.8 构建成功

wps24 

 

wps25 

 

wps26 

 

# 所有服务在eureak集群中正常注册

wps27 

4.9 测试

1 gitlab中修改portal-service前端数据

wps28 

wps29 

 

2 重新部署portal服务到172.16.1.66(webservers2)节点

wps30 

 

3 在浏览器中循环刷新微服务项目,会发现标题循环发生改变

http://portal.ctnrs.com/

 

# 出现添加的内容

wps31 

 

# 没有出现添加的内容

wps32 

5 微服务全链路监控

5.1 说明

1 全链路监控是什么

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。这些服务可能不同编程语言开发,不同团队开发,可能部署很多副本。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决问题。全链路监控组件就在这样的问题背景下产生了。全链路性能监控从整体维度到局部维度展示各项指标,将跨应用的所有调用链性能信息集中展现,可方便度量整体和局部性能,并且方便找到故障产生的源头,生产上可极大缩短故障排除时间。

wps33 

 

2 全链路监控解决什么问题

(1) 请求链路追踪:通过分析服务调用关系,绘制运行时拓扑信息,可视化展示

(2) 调用情况衡量:各个调用环节的性能分析,例如吞吐量、响应时间、错误次数

(3) 容器规划参考:扩容/缩容、服务降级、流量控制

(4) 运行情况反馈:告警,通过调用链结合业务日志快速定位错误信息

 

3 全链路监控系统选择依据

全链路监控系统有很多,应从这几方面选择:

(1) 探针的性能消耗

APM组件服务的影响应该做到足够小,数据分析要快,性能占用小。

(2) 代码的侵入性

即也作为业务组件,应当尽可能少入侵或者无入侵其他业务系统,对于使用方透明,减少开发人员的负担。

(3) 监控维度

分析的维度尽可能多。

(4) 可扩展性

一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性。能够支持的组件越多当然越好。

主流系统:skywalkingpinpointzipkin

 

4 Pinpoint介绍

Pinpoint是一个APM(应用程序性能管理)工具,适用于用Java/PHP编写的中大型分布式系统。

特性:

(1) 服务器地图(ServerMap

通过可视化分布式系统的模块和他们之间的相互联系来理解系统拓扑。点击某个节点会展示这个模块的详情,比如它当前的状态和请求数量。

(2) 实时活动线程图(Realtime Active Thread Chart

实时监控应用内部的活动线程。

(3) 请求/响应分布图(Request/Response Scatter Chart

长期可视化请求数量和应答模式来定位潜在问题。通过在图表上拉拽可以选择请求查看更多的详细信息。

(4) 调用栈(CallStack

在分布式环境中为每个调用生成代码级别的可视图,在单个视图中定位瓶颈和失败点。

(5) 检查器(Inspector

查看应用上的其他详细信息,比如CPU使用率,内存/垃圾回收,TPS,和JVM参数。

5.2 Pinpoint部署

172.16.1.70节点上操作

1 环境准备

(1) 安装docker环境(省略步骤)

(2) 安装docker-compose

1) 下载二进制文件

# curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64 -o /usr/bin/docker-compose

 

2) 添加可执行权限

# chmod +x /usr/bin/docker-compose

 

2 部署

# git clone https://github.com/pinpoint-apm/pinpoint-docker.git

# cd pinpoint-docker

# docker-compose pull

# docker-compose up -d

# docker-compose ps

wps34 

wps35 

 

访问url地址:http://172.16.1.70:8079

 

5.3 Pinpoint Agent部署

1 下载pinpoint agent jar

wps36 

-javaagent:${pinpointPath}/pinpoint-bootstrap-1.8.5.jar

-Dpinpoint.applicationName=

-Dpinpoint.agentId=

 

https://github.com/pinpoint-apm/pinpoint/releases/download/1.8.5/pinpoint-agent-1.8.5.tar.gz

 

TomCat

# catalina.sh

CATALINA_OPTS="$CATALINA_OPTS -javaagent:${pinpointPath}/pinpoint-bootstrap-1.8.5.jar"

CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.applicationName=portal"

CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.agentId=172.16.1.65"

 

2 部署

portal服务为例,在172.16.1.65节点上操作

(1) 配置pinpoint agent连接pinpoint服务端

# mkdir -p /data/ms/portal/pinpoint-agent/

# cd /data/ms/portal/pinpoint-agent/

# tar -xzf pinpoint-bootstrap-1.8.5.jar

# vim pinpoint.config

profiler.collector.ip=172.16.1.70

 

(2) pinpoint agent加入到portal前端服务中

# vim /usr/lib/systemd/system/portal.service

[Unit]

Description=portal

Documentation=portal

[Service]

ExecStart=/usr/local/jdk/bin/java -jar -javaagent:/data/ms/portal/pinpoint-agent/pinpoint-bootstrap-1.8.5.jar -Dpinpoint.applicationName=portal -Dpinpoint.agentId=172.16.1.65 /data/ms/port

al/portal-service.jarExecReload=/bin/kill -HUP

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

(3) 重启portal服务

# systemctl daemon-reload

# systemctl restart portal.service

 

3 在浏览器中多次访问http://portal.ctnrs.com/,然后在pinpoint中查看调用关系图

wps37 

5.4 重点关注的监控指标

1 堆内存

2 GCC

3 CPU使用率

4 堆栈跟踪

5 接口状态

6 吞吐量、相应时间

6 Java程序调用与故障排查工具

6.1 java常用工具

1 jps # 显示JVM进程状态

2 jstack # 打印Java进程的线程堆栈信息

3 jmap # 打印共享对象内存映射或堆内存详细信息

4 jstat # 监控JVM的统计数

 

6.2 程序调优参数

portal服务为例

1 配置调优参数

# vim /usr/lib/systemd/system/portal.service

[Unit]

Description=portal

Documentation=portal

[Service]

ExecStart=/usr/local/jdk/bin/java -Xms512m -Xmx2g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/data/ms/portal/gc.log -jar /data/ms/portal/portal-

service.jarExecReload=/bin/kill -HUP

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

2 重启portal服务

# systemctl daemon-reload

# systemctl restart portal.service

 

3 查看堆栈信息

# jps -l

2066 sun.tools.jps.Jps

1960 /data/ms/portal/portal-service.jar

 

# jmap -heap 1960

wps38 

6.3 故障排查

1 堆内存溢出

(1) 可能原因

1) 堆内存不足,设置容量较小

2) 代码Bug,对象不释放

 

(2) 堆内存内存溢出日志错误

老年代内存不足

java.lang.OutOfMemoryError:Javaheapspace

2 Java进程CPU利用率占用很高

(1) 可能原因

1) 频繁GC

2) 代码Bug

 

(2) 定位占用CPU高的代码

1) 查看占用资源最多的Java进程的PID

# top

wps39 

 

2) 查看进程下占用CPU使用率最多的线程PID

# top -Hp 2268

wps40 

 

3) 将线程PID转换为十六进制

# printf "%x " 2279

8e7

 

4) jstack获取进程堆栈信息,过滤出这个线程的

格式:jstack <进程PID> |grep <十六进制> -A 30

# jstack 2268 | grep 8e7 -A 30

wps41 

 

原文地址:https://www.cnblogs.com/LiuChang-blog/p/14704169.html