• 微服务项目运维管理



    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 

     

  • 相关阅读:
    [Xcode 实际操作]七、文件与数据-(6 )通过通知中心,实现监听和处理程序退出事件的功能
    [Xcode 实际操作]七、文件与数据-(5 )复制、移动、删除文件和删除文件夹
    [Xcode 实际操作]七、文件与数据-(4 )遍历文件夹中的文件
    [Xcode 实际操作]七、文件与数据-(3)创建文本文件、属性列表文件、图片文件
    自己定义控件-GifView
    HDU 3591 多重背包
    Atitit.列表页面and条件查询的实现最佳实践(2)------翻页 分页 控件的实现java .net php
    HDU1950-Bridging signals-最长上升子序列
    Scilab 的画图函数(2)
    POJ 3984 迷宫问题
  • 原文地址:https://www.cnblogs.com/LiuChang-blog/p/14704169.html
Copyright © 2020-2023  润新知