YONGFEIUALL

izheyi.com


  • Home

  • Archives

  • Categories

  • Tags

  • About

  • Search

参观军事博物馆

Posted on 2018-06-24 | In 丁丁 |

本来是去动物园,太热了,动物也都不怎么能看到,游乐园也不想玩。

就去了军事博物馆。看到那个年代的机器也是很复杂的,感受到人在武器,战争面前,显示那么的渺小和脆弱。













利用线程Dump来查找高消耗CPU代码

Posted on 2018-06-20 | In Performance Testing |

对于CPU消耗高的代码,可以用下面的方法来进行定位分析。

前提

运行一段Java代码,让它消耗CPU。

定位

  1. 用top查找出高消耗CPU PID

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@Automation logs]# top
    top - 10:14:33 up 19:47, 4 users, load average: 0.48, 0.41, 0.32
    Tasks: 189 total, 1 running, 188 sleeping, 0 stopped, 0 zombie
    Cpu(s): 11.8%us, 15.0%sy, 0.0%ni, 70.4%id, 0.0%wa, 1.4%hi, 1.4%si, 0.0%st
    Mem: 3389932k total, 3284936k used, 104996k free, 182736k buffers
    Swap: 3522556k total, 11740k used, 3510816k free, 1144964k cached

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    14538 root 20 0 1916m 52m 10m S 30.8 1.6 8:33.55 java
    14087 root 20 0 100m 4688 3504 S 16.3 0.1 14:21.79 sshd
    10032 root 20 0 1125m 277m 49m S 4.0 8.4 99:02.94 firefox

  2. 用top -p <PID>查找出线程ID - (输入H查看所有线程的统计信息)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@Automation logs]# top -p 14538
    top - 10:21:53 up 19:54, 4 users, load average: 0.48, 0.44, 0.35
    Tasks: 3 total, 0 running, 3 sleeping, 0 stopped, 0 zombie
    Cpu(s): 11.9%us, 15.8%sy, 0.0%ni, 69.9%id, 0.0%wa, 0.9%hi, 1.6%si, 0.0%st
    Mem: 3389932k total, 3243372k used, 146560k free, 182704k buffers
    Swap: 3522556k total, 12700k used, 3509856k free, 1105400k cached

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    14539 root 20 0 1916m 52m 10m S 33.0 1.6 10:53.38 java
    14540 root 20 0 1916m 52m 10m S 25.6 1.6 0:00.77 java
    14538 root 20 0 1916m 52m 10m S 0.0 1.6 0:00.00 java

  3. 用jstack <PID>做线程Dump

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    [root@Automation logs]# jstack 14538
    2018-06-20 10:18:12
    Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode):

    "Attach Listener" daemon prio=10 tid=0x00007f6cbc001000 nid=0x38fe waiting on condition [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "Service Thread" daemon prio=10 tid=0x00007f6ce8093000 nid=0x38d4 runnable [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "C2 CompilerThread1" daemon prio=10 tid=0x00007f6ce8090800 nid=0x38d3 waiting on condition [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "C2 CompilerThread0" daemon prio=10 tid=0x00007f6ce808d800 nid=0x38d2 waiting on condition [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "Signal Dispatcher" daemon prio=10 tid=0x00007f6ce808b000 nid=0x38d1 runnable [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "Finalizer" daemon prio=10 tid=0x00007f6ce806a800 nid=0x38d0 in Object.wait() [0x00007f6cd7efd000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000000cc4028c0> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0x00000000cc4028c0> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

    "Reference Handler" daemon prio=10 tid=0x00007f6ce8068800 nid=0x38cf in Object.wait() [0x00007f6cd7ffe000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000000cc4025c0> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    - locked <0x00000000cc4025c0> (a java.lang.ref.Reference$Lock)

    "main" prio=10 tid=0x00007f6ce8008800 nid=0x38cb runnable [0x00007f6ceec18000]
    java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:345)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x00000000cc405728> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x00000000cc405800> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.write(PrintStream.java:527)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at java.io.PrintStream.print(PrintStream.java:597)
    at java.io.PrintStream.println(PrintStream.java:736)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at TestA.testA(TestA.java:10)
    at TestA.main(TestA.java:3)

    "VM Thread" prio=10 tid=0x00007f6ce8064000 nid=0x38ce runnable

    "GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f6ce801e000 nid=0x38cc runnable

    "GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f6ce8020000 nid=0x38cd runnable

    "VM Periodic Task Thread" prio=10 tid=0x00007f6ce809e000 nid=0x38d5 waiting on condition

    JNI global references: 138
  4. 转换(十进制 - 十六进制)nid

    1
    14539 --> 38cb
  5. 在Dump中查找相应nid

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    "main" prio=10 tid=0x00007f6ce8008800 nid=0x38cb runnable [0x00007f6ceec18000]
    java.lang.Thread.State: RUNNABLE
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:345)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    - locked <0x00000000cc405728> (a java.io.BufferedOutputStream)
    at java.io.PrintStream.write(PrintStream.java:482)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
    - locked <0x00000000cc405800> (a java.io.OutputStreamWriter)
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
    at java.io.PrintStream.write(PrintStream.java:527)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at java.io.PrintStream.print(PrintStream.java:597)
    at java.io.PrintStream.println(PrintStream.java:736)
    - locked <0x00000000cc405708> (a java.io.PrintStream)
    at TestA.testA(TestA.java:10)
    at TestA.main(TestA.java:3)

基本上一定位一个准。

jvisualvm通过jmx监控Tomcat

Posted on 2018-06-17 | In Performance Testing |

用JVisualVM连接远程JVM,监控系统运行性能参数。

要在监控的Server上,在tomcat的catalina.sh 中添加如下参数:

1
2
# OS specific support.  $var _must_ be set to either true or false.
JAVA_OPTS='-Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false'

配置后重启Tomcat,发现在连接不上。 做以下配置

  • Host Name

    1
    2
    3
    4
    5
    [root@Automation bin]# vi /etc/sysconfig/network

    NETWORKING=yes
    HOSTNAME=Automation
    NTPSERVERARGS=iburst
  • Hosts

    1
    2
    3
    4
    5
    6
    7
    8
    [root@Automation bin]# vi /etc/hosts

    127.0.0.1 localhost.localdomain localhost localhost4 localhost4.localdomain4
    ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

    #10.22.1.13 gitserver Automation

    10.24.33.82 Automation

最终结果如下,可以查看查看远程CPU、堆、类、线程的使用情况了。

Python + Selenium: Page Object and Page Factory

Posted on 2018-06-10 | In Selenium Webdriver |

基于种种原因,简单地对Python + Selenium的UI自动化做了一个简单的搭建。一些简单的分层:

  • conf: 一些配置文件,如网址,Browser Type
  • data: 数据驱动的数据
  • pages: Page对象
  • report: HTML报告,Screenshot
  • tests: 脚本
  • utils: 公共的方法,封闭Selenium,处理csv

python_selenium_page_object_example

Page Object

  1. 做了一个BasicPage类,对Selenium做了简单封装

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class BasicPage(object):

    def __init__(self, driver):
    self.driver = driver

    def open_page(self, url):
    """**Description**::
    open the page
    """

    self.driver.get(url)
    self.driver.maximize_window()

    def input_text(self, locator, value):
    """**Description**::
    Fill value to the element located by locator

    :param locator:The locator to locate the element.
    :param value:value to set to the element
    :return:
    """

    element = self._find_web_element(locator)
    element.send_keys(value)
    return self
  2. Page Object实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from utils.page import *


    class BaiduPage(BasicPage):

    search_box = ('id', 'kw')
    search_button = ('id', 'su')

    def search(self, keywords):
    self.input_text(self.search_box, keywords)
    self.click_element(self.search_button)
  3. 对Browser进行封装,利用Pytest Fixture实现每个脚本运行前运行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    from selenium import webdriver
    import pytest
    from conf.const import Const


    @pytest.fixture(scope='function', params=[Const.browser])
    def start_browser(request):
    """**Description**::
    start browser
    """

    name = request.param

    try:
    if name == "firefox" or name == "Firefox" or name == "ff":
    print("start browser name :Firefox")
    driver = webdriver.Firefox()
    return driver
    elif name == "chrome" or name == "Chrome":
    print("start browser name :Chrome")
    driver = webdriver.Chrome()
    return driver
    elif name == "ie" or name == "Ie":
    print("start browser name :Ie")
    driver = webdriver.Ie()
    return driver
    elif name == "phantomjs" or name == "Phantomjs":
    print("start browser name :phantomjs")
    driver = webdriver.PhantomJS()
    return driver
    else:
    print("Not found this browser,You can use 'firefox', 'chrome', 'ie' or 'phantomjs'")
    except Exception as msg:
    print("Couldn't start browser:%s" % str(msg))
  4. 脚本层实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from pages.page_object import *
    from conf.const import *


    class TestPO():
    def test_baidu(self, start_browser):
    baidu = BaiduPage(start_browser)
    baidu.open_page(URL.baidu)
    baidu.search("selenium")
    start_browser.close()

Page Factory

Python跟Java不一样,没有专门的方法来实现,在网上看到有人做了个实现,只是在这里做了个简单的实验:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
__all__ = ['cacheable', 'callable_find_by', 'property_find_by']


def cacheable_decorator(lookup):
def func(self):
if not hasattr(self, '_elements_cache'):
self._elements_cache = {} # {callable_id: element(s)}
cache = self._elements_cache

key = id(lookup)
if key not in cache:
cache[key] = lookup(self)
return cache[key]

return func


cacheable = cacheable_decorator

_strategy_kwargs = ['id_', 'xpath', 'link_text', 'partial_link_text',
'name', 'tag_name', 'class_name', 'css_selector']


def _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs):
def func(self):
# context - driver or a certain element
if context:
ctx = context() if callable(context) else context.__get__(self) # or property
else:
ctx = getattr(self, driver_attr)

# 'how' AND 'using' take precedence over keyword arguments
if how and using:
lookup = ctx.find_elements if multiple else ctx.find_element
return lookup(how, using)

if len(kwargs) != 1 or list(kwargs.keys())[0] not in _strategy_kwargs:
raise ValueError(
"If 'how' AND 'using' are not specified, one and only one of the following "
"valid keyword arguments should be provided: %s." % _strategy_kwargs)

key = list(kwargs.keys())[0];
value = kwargs[key]
suffix = key[:-1] if key.endswith('_') else key # find_element(s)_by_xxx
prefix = 'find_elements_by' if multiple else 'find_element_by'
lookup = getattr(ctx, '%s_%s' % (prefix, suffix))
return lookup(value)

return cacheable_decorator(func) if cacheable else func


def callable_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='driver',
**kwargs):

return _callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs)


def property_find_by(how=None, using=None, multiple=False, cacheable=False, context=None, driver_attr='driver',
**kwargs):

return property(_callable_find_by(how, using, multiple, cacheable, context, driver_attr, **kwargs))

Page:

1
2
3
4
5
6
7
8
9
10
11
12
from utils.page import *
from utils.pageobject_support import callable_find_by as by


class BaiduPage(BasicPage):

search_box = by(id_="kw")
search_button = by(id_='su')

def search(self, keywords):
self.search_box().send_keys(keywords)
self.search_button().click()

除了爱孩子,没有任何一个理由生二胎

Posted on 2018-06-06 | In 随想 |

二胎,在中国是个永远逃不掉的话题,有的人甚至三胎都提上了日程。

二孩政策都放开了,你不生就是自私;重男轻女的思想,没有男孩就是无后;一个孩子太单了,给她有个伴;当你老了,多个孩子好养老;你看周围的朋友都生了,你也应该生……太多的所谓正确的理由和建议充斥在耳旁,但生与不生,只有你知道自己内心最真实的想法。

想生二胎,首先想到的就是经济基础,网上有太多计算,生二胎要花多少多少钱,特别是在大城市,感觉一般工薪族是生不起的。时代不同了,养孩子远不止吃饱穿好,就说一点,教育,记得奇葩说里说过不要假装现代社会金钱不重要,不要误导年轻人,没有钱也能很好养育孩子。

孩子好生不好养,最主要的还是时间和精力。你有没有内心强大到再来一轮?有没有人给你带孩子?你能不能给她足够多的陪伴?你能不能平衡好大宝和二宝的关系?

最近跟闺女聊了很多,发现她并不是大人眼中想的那么独立,在新环境中她也有委屈,有愤怒,有失落,在面对她的种种问题的时候,我却束手无策,心理难免还是会有一些不好受。浮躁的社会,跟风攀比的家长,眼花缭乱的培训班,让孩子无所适从。在教育孩子上面还有很长的路要走,实在是没有准备好再有一个孩子,应该怎样让她们都能在这个浮躁的社会里成为幸福的人。

生与不生都是自己的问题,每个家庭的情况不同,选择自然也不同。生育是一种能力,不是一种义务,除了爱孩子,没有任何一个理由生二胎。

参观北京天文馆

Posted on 2018-06-03 | In 丁丁 |

上次来过一次,来的晚了票都卖完了,这次没开馆之前就到了。

a馆是老馆,就一个小展厅,球幕电影也一般;b馆是新馆,还可以吧。总体感觉,要是没有或者有少量天文知识的,不听讲解的话,其实啥也看不太明白了。孩子来了也是跟着看个热闹。













少先队员入队 - Mini世界实践

Posted on 2018-06-01 | In 丁丁 |

期盼了很长时间,也练习了很长时间,系红领巾,站队,唱歌。。。终于入队了。

正好赶上六一儿童节,学校有心的带领着大家去迷你世界体验馆感受了一把。






CI/CD - 环境搭建(7) - 集成Terraform

Posted on 2018-05-31 | In Product Delivery |

Goal

实现Jenkins + Terraform在AWS上创建基本环境。

Prerequisites

  • Terraform,please refer: Terraform知识

Terraform Config

创建main.tf,并push到Github上。

1
2
3
4
5
6
7
8
9
10
11
provider "aws" {
region = "us-east-1"
}

resource "aws_instance" "yongfeiuall" {
ami = "ami-1853ac65"
instance_type = "t2.micro"
tags{
Name = "integration with jenkins"
}
}

Jenkins Config

创建Pipeline Job:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
node {

stage('Preparation') { // for display purposes
// Get some code from a GitHub repository
git credentialsId: 'ee7a726b-e672-424d-9b78-e8015668d55a', url: 'git@github.com:yongfeiuall/pipeline-terraform-example.git'
}

stage('variable file') {
sh 'sudo cp ~/variables.tf ~/.jenkins/workspace/ci-terraform'
}

stage('init'){
sh "terraform --version"
sh "terraform init"
}

stage('plan'){
sh "terraform plan"
}

stage('apply'){
sh "terraform apply -auto-approve"
}
}

说明:

  • Terraform预先安装在了Server上,没有用Jenkins安装
  • AWS access key和secret key不能公开,所以加了stage('variable file),提前放到Server上去
  • terraform apply加上-auto-approve

运行

南戴河游玩

Posted on 2018-05-27 | In 丁丁 |

两周前的周末跟妈妈去了南戴河玩,妈妈公司组织的活动,爸爸没有去。

玩的很开心,下次带你看更大的海^_^












CI/CD - 环境搭建(6) - 实现Salt部署

Posted on 2018-05-23 | In Product Delivery |

Goal

利用Salt,从Artifactory上Get Build,并部署。

Prerequisites

  • 集成Artifactory,please refer: 集成Artifactory
  • Salt安装,refer:安装SaltStack

Salt Config

  1. 创建Salt State

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    [root@Automation ~]# cd /srv/salt/
    [root@Automation salt]# ls
    artifact.sls file.sls _grains mysql.sls top.sls webserver.sls
    [root@Automation salt]# cat artifact.sls
    spring_module_downloaded:
    artifactory.downloaded:
    - artifact:
    artifactory_url: http://192.168.220.129:8081/artifactory
    repository: 'libs-release-local'
    artifact_id: 'ci-example'
    group_id: 'com.izheyi'
    packaging: 'jar'
    classifier: 'sources'
    version: '1.0.1'
    - target_file: /opt/artifact_project.jar
    [root@Automation salt]# cat top.sls
    base:
    '*':
    - artifact
  2. 执行Command

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [root@Automation salt]# salt '*' state.highstate
    192.168.220.131:
    ----------

    ID: spring_module_downloaded
    Function: artifactory.downloaded
    Result: True
    Comment: Artifact downloaded from URL: http://192.168.220.129:8081/artifactory/libs-release-local/com/izheyi/ci-example/1.0.1/ci-example-1.0.1.jar
    Started: 02:02:49.649477
    Duration: 860.559 ms
    Changes:
    ----------
    downloaded_file:
    /opt/artifact_project.jar

    Summary
    ------------

    Succeeded: 1 (changed=1)
    Failed: 0
    ------------

    Total states run: 1
    [root@Automation salt]#
  3. 去Minion检查

    1
    2
    3
    [root@Automation opt]# ls
    alfresco-community artifact_project.jar my_new_directory rh
    [root@Automation opt]#
  4. 用Command运行

    1
    [root@Automation salt]# salt '*' cmd.run 'cd /opt; java -jar artifact_project.jar'
  5. 检查成功

    1
    2
    3
    [root@Automation opt]# curl http://192.168.220.131:8080/
    Hello World!
    [root@Automation opt]#

With Jenkins

用Shell:

1
2
3
sshpass -p yongfei.hu ssh -o "StrictHostKeyChecking no"  root@192.168.220.130 "salt '*' state.highstate"

sshpass -p yongfei.hu ssh -o "StrictHostKeyChecking no" root@192.168.220.130 "salt '*' cmd.run 'cd /opt; java -jar artifact_project.jar'"

1…121314…40
唐胡璐

唐胡璐

i just wanna live while i am alive

393 posts
42 categories
74 tags
RSS
LinkedIn Weibo GitHub E-Mail
Creative Commons
© 2022 唐胡璐
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4