Author: ephuizi

  • rpm快速查询软件包信息

    rpm -qi $(rpm -qf $(which ls |grep -v ^alias))

    (more…)

  • go_1.21泛型示例

    package demo
    
    import (
        "math/rand"
        "time"
    )
    
    // 定义泛型接口
    type RandomElementer[T any] interface {
        // 返回一个随机的元素,如果集合为空,返回(zero, false)
        RandomElement() (T, bool)
    }
    
    func MustRandom[T any](collection RandomElementer[T]) T {
        val, ok := collection.RandomElement()
        if !ok {
            panic("collection is empty.")
        }
        return val
    }
    
    // MyList 泛型集合.
    type MyList[T any] []T
    
    // MyList 实现接口RandomElement
    func (l MyList[T]) RandomElement() (T, bool) {
        n := len(l)
        if n == 1 {
            return l[0], true
        }
    
        r := rand.New(rand.NewSource(time.Now().UnixNano()))
        return l[r.Intn(n)], true
    }
    
    
    package demo
    
    import (
        "reflect"
        "testing"
    )
    
    func TestMustRandom(t *testing.T) {
        type args struct {
            collection RandomElementer[int]
        }
        tests := []struct {
            name string
            args args
            want int
        }{
            // TODO: Add test cases.
            {
                "case1",
                args{MyList[int]{1, 1, 1}},
                1,
            },
            {
                "case2",
                args{MyList[int]{6, 6, 6}},
                6,
            },
        }
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := MustRandom(tt.args.collection); !reflect.DeepEqual(got, tt.want) {
                    t.Errorf("MustRandom() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    
  • linux原生支持的格式化文件方法

    利用python格式json

    python -m json.tool

    echo '{"list":[{"a":"1"},{"b":"2"}]}' |python -m json.tool
    
    cat x.json
    {"list":[{"a":"1"},{"b":"2"}]}
    
    python -m json.tool  x.json
    {
        "list": [
            {
                "a": "1"
            },
            {
                "b": "2"
            }
        ]
    }
    

    利用python计算

    python -c ‘print(123+456+7.89)’

    xmllint格式化xml文件

    xmllint –format pom.xml

  • centos7使用接入iscsi设备

    centos7 安装Open ISCSI 启动器 软件包

    yum install iscsi-initiator-utils -y

    查看 iscsi 启动器名称

    [root@mulangcloud ~]# cat /etc/iscsi/initiatorname.iscsi
    InitiatorName=iqn.1994-05.com.redhat:a5c39efe925
    

    扫描 iscsi target

    192.168.8.73 iscsi 服务器.

    [root@mulangcloud ~]#  iscsiadm -m discovery -t st -p 192.168.8.73
    192.168.8.73:3260,1 iqn.2020-03.com.ml:target
    

    扫描 open iscsi 客户端已经登陆的 session

    在完成目标发现后,即可以登录到相应的节点,使用目标设备提供的存储空间.
    -T后面跟target名称,--login等同于-l

    [root@mulangcloud ~]#  iscsiadm -m session
    tcp: [4] 192.168.8.73:3260,1 iqn.2020-03.com.ml:target (non-flash)
    
    [root@mulangcloud ~]#  iscsiadm -m session -r 4  --rescan
    Rescanning session [sid: 4, target: iqn.2020-03.com.ml:target, portal: 192.168.8.73,3260]
    
    [root@mulangcloud ~]# ls -l /dev/disk/by-path/
    total 0
    lrwxrwxrwx 1 root root  9 Jul 24 09:27 ip-192.168.8.73:3260-iscsi-iqn.2020-03.com.ml:target-lun-0 -> ../../sdd
    lrwxrwxrwx 1 root root 10 Jul 24 09:27 ip-192.168.8.73:3260-iscsi-iqn.2020-03.com.ml:target-lun-0-part1 -> ../../sdd1
    lrwxrwxrwx 1 root root 10 Jul 24 09:27 ip-192.168.8.73:3260-iscsi-iqn.2020-03.com.ml:target-lun-0-part2 -> ../../sdd2
    lrwxrwxrwx 1 root root  9 Jul 24 09:25 ip-192.168.8.73:3260-iscsi-iqn.2020-03.com.ml:target-lun-1 -> ../../sde
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0 -> ../../sda
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part1 -> ../../sda1
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part2 -> ../../sda2
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part3 -> ../../sda3
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part4 -> ../../sda4
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part5 -> ../../sda5
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part6 -> ../../sda6
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part7 -> ../../sda7
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-2.0 -> ../../sdb
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-3.0 -> ../../sdc
    
    [root@mulangcloud ~]# echo 1 > /sys/block/sdd/device/delete
    [root@mulangcloud ~]# echo 1 > /sys/block/sde/device/delete
    
    [root@mulangcloud ~]# ls -l /dev/disk/by-path/
    total 0
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0 -> ../../sda
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part1 -> ../../sda1
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part2 -> ../../sda2
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part3 -> ../../sda3
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part4 -> ../../sda4
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part5 -> ../../sda5
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part6 -> ../../sda6
    lrwxrwxrwx 1 root root 10 Jul 19 08:40 pci-0000:00:1f.2-ata-1.0-part7 -> ../../sda7
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-2.0 -> ../../sdb
    lrwxrwxrwx 1 root root  9 Jul 19 08:40 pci-0000:00:1f.2-ata-3.0 -> ../../sdc
    
    [root@mulangcloud ~]# iscsiadm -m node -T iqn.2020-03.com.ml:target -u
    Logging out of session [sid: 4, target: iqn.2020-03.com.ml:target, portal: 192.168.8.73,3260]
    Logout of [sid: 4, target: iqn.2020-03.com.ml:target, portal: 192.168.8.73,3260] successful.
    

    other

    列出所有target
    iscsiadm -m node
    
    连接所有target
    iscsiadm -m node -L all
    
    连接指定target
    iscsiadm -m node -T iqn.... -p 172.29.88.62 --login
    
    使用如下命令可以查看配置信息
    iscsiadm -m node -o show -T iqn.2000-01.com.synology:rackstation.exservice-bak
    
    查看目前 iSCSI target 连接状态
    iscsiadm -m session
    iscsiadm: No active sessions.
    (目前没有已连接的 iSCSI target)
    
    断开所有target
    iscsiadm -m node -U all
    
    断开指定target
    iscsiadm -m node -T iqn... -p 172.29.88.62 --logout
    
    删除所有node信息
    iscsiadm -m node --op delete
    
    删除指定节点(/var/lib/iscsi/nodes目录下,先断开session)
    iscsiadm -m node -o delete -name iqn.2012-01.cn.nayun:test-01
    
    删除一个目标(/var/lib/iscsi/send_targets目录下)
    iscsiadm --mode discovery -o delete -p 172.29.88.62:3260
    
  • arthas常用的命令

    查询静态变量

    [arthas@174072]$ getstatic com.mulang.octopus.Main standAloneStorageNode
    field: standAloneStorageNode
    @Boolean[true]
    Affect(row-cnt:1) cost in 6 ms.
    

    使用ognl方式

    [arthas@227877]$  ognl "@java.nio.Bits@RESERVED_MEMORY"
    @AtomicLong[
        serialVersionUID=@Long[1927816293512124184],
        VM_SUPPORTS_LONG_CAS=@Boolean[true],
        U=@Unsafe[jdk.internal.misc.Unsafe@12b9a7fa],
        VALUE=@Long[16],
        value=@Long[9515349],
        serialVersionUID=@Long[-8742448824652078965],
    ]
    [arthas@227877]$
    [arthas@227877]$  ognl "@java.nio.Bits@RESERVED_MEMORY.get()"
    @Long[9515349]
    [arthas@227877]$
    

    调用没有参数的静态命令.

    #public static DataStoreType typeDataStore()
    
    [arthas@174072]$ ognl '@com.mulang.octopus.blockstore.BlockServiceProxy@typeDataStore()'
    @DataStoreType[LOCAL_DISK]
    

    调用有参数的静态命令.

    #public static long diskFreeCapacity(int serverId, int diskId) throws IOException
    
    [arthas@11123]$ ognl  '@com.mulang.octopus.blockstore.BlockServiceProxy@diskFreeCapacity(3,40001)'
    @Long[211085709312]
    

    解决方法重载

    通过制定参数个数的形式解决不同的方法签名

    tt -t *Test print params.length\=\=1
    

    通过制定参数个数的形式解决不同的方法签名,如果参数个数一样,你还可以这样写

    tt -t *Test print ‘params[1] instanceof Integer’

    解决指定参数

    tt -t *Test print params[0].mobile\=\=”13989838402″

    构成条件表达式的 Advice 对象

    表达式核心变量

    public class Advice {
    
        private final ClassLoader loader;   //本次调用类所在的 ClassLoader
        private final Class<?> clazz;       //本次调用类的 Class 引用
        private final ArthasMethod method;  //本次调用方法反射引用
        private final Object target;        //本次调用类的实例
        //本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
        private final Object[] params;
        //本次调用返回的对象。当且仅当 isReturn==true 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null
        private final Object returnObj;
        //本次调用抛出的异常。当且仅当 isThrow==true 成立时有效,表明方法调用是以抛出异常的方式结束。
        private final Throwable throwExp;
        //辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBefore==true 成立,同时 isThrow==false 和 isReturn==false,因为在方法刚开始时,还无法确定方法调用将会如何结束。
        private final boolean isBefore;
        //辅助判断标记,当前的方法调用以抛异常的形式结束。
        private final boolean isThrow;
        //辅助判断标记,当前的方法调用以正常返回的形式结束。
        private final boolean isReturn;
    
        // getter/setter
    }
    

    所有变量都可以在表达式中直接使用,如果在表达式中编写了不符合 OGNL 脚本语法或者引入了不在表格中的变量,则退出命令的执行;

    热更新某个类

    class/classloader 相关

    • classloader – 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource
    • dump – dump 已加载类的 byte code 到特定目录
    • jad – 反编译指定已加载类的源码
    • mc – 内存编译器,内存编译.java文件为.class文件
    • redefine – 加载外部的.class文件,redefine 到 JVM 里
    • retransform – 加载外部的.class文件,retransform 到 JVM 里
    • sc – 查看 JVM 已加载的类信息
    • sm – 查看已加载类的方法信息
    $ retransform /tmp/MathGame.class
    retransform success, size: 1, classes:
    demo.MathGame
    
    

    Note:

    • redefine 的 class 不能修改、添加、删除类的 field 和 method,包括方法参数、方法名称及返回值
    • 如果 mc 失败,可以在本地开发环境编译好 class 文件,上传到目标系统,使用 redefine 热加载 class

    tt 和 watch

    tt

    • 需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确 的值。这也是为什么 watch 命令存在的意义
    表格字段 字段解释
    INDEX 时间片段记录编号,每一个编号代表着一次调用,后续 tt 还有很多命令都是基于此编号指定记录操作,非常重要。
    TIMESTAMP 方法执行的本机时间,记录了这个时间片段所发生的本机时间
    COST(ms) 方法执行的耗时
    IS-RET 方法是否以正常返回的形式结束
    IS-EXP 方法是否以抛异常的形式结束
    OBJECT 执行对象的hashCode(),注意,曾经有人误认为是对象在 JVM 中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
    CLASS 执行的类名
    METHOD 执行的方法名
    [arthas@15217]$ tt -t demo.MathGame primeFactors -n 3
    Press Q or Ctrl+C to abort.
    Affect(class count: 1 , method count: 1) cost in 100 ms, listenerId: 1
     INDEX       TIMESTAMP                    COST(ms)      IS-RET      IS-EXP      OBJECT                CLASS                                      METHOD
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     1000        2023-03-10 03:37:42          1.419275      true        false       0x232204a1            MathGame                                   primeFactors
     1001        2023-03-10 03:37:43          0.144813      false       true        0x232204a1            MathGame                                   primeFactors
     1002        2023-03-10 03:37:44          4.481957      true        false       0x232204a1            MathGame                                   primeFactors
    Command execution times exceed limit: 3, so command will exit. You can set it with -n option.
    [arthas@15217]$ tt -t demo.MathGame primeFactors -n 2
    Press Q or Ctrl+C to abort.
    Affect(class count: 1 , method count: 1) cost in 28 ms, listenerId: 2
     INDEX       TIMESTAMP                    COST(ms)      IS-RET      IS-EXP      OBJECT                CLASS                                      METHOD
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     1003        2023-03-10 03:38:15          0.128059      true        false       0x232204a1            MathGame                                   primeFactors
     1004        2023-03-10 03:38:16          0.028727      true        false       0x232204a1            MathGame                                   primeFactors
    Command execution times exceed limit: 2, so command will exit. You can set it with -n option.
    
    #list
    [arthas@15217]$ tt -l
     INDEX       TIMESTAMP                    COST(ms)      IS-RET      IS-EXP      OBJECT                CLASS                                      METHOD
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     1000        2023-03-10 03:37:42          1.419275      true        false       0x232204a1            MathGame                                   primeFactors
     1001        2023-03-10 03:37:43          0.144813      false       true        0x232204a1            MathGame                                   primeFactors
     1002        2023-03-10 03:37:44          4.481957      true        false       0x232204a1            MathGame                                   primeFactors
     1003        2023-03-10 03:38:15          0.128059      true        false       0x232204a1            MathGame                                   primeFactors
     1004        2023-03-10 03:38:16          0.028727      true        false       0x232204a1            MathGame                                   primeFactors
    Affect(row-cnt:5) cost in 3 ms.
    [arthas@15217]$ tt -i 1003
     INDEX          1003
     GMT-CREATE     2023-03-10 03:38:15
     COST(ms)       0.128059
     OBJECT         0x232204a1
     CLASS          demo.MathGame
     METHOD         primeFactors
     IS-RETURN      true
     IS-EXCEPTION   false
     PARAMETERS[0]  @Integer[162701]
     RETURN-OBJ     @ArrayList[
                        @Integer[7],
                        @Integer[11],
                        @Integer[2113],
                    ]
    Affect(row-cnt:1) cost in 4 ms.
    
    #replay
    [arthas@15217]$ tt -i 1003 -p
     RE-INDEX       1003
     GMT-REPLAY     2023-03-10 04:37:14
     OBJECT         0x232204a1
     CLASS          demo.MathGame
     METHOD         primeFactors
     PARAMETERS[0]  @Integer[162701]
     IS-RETURN      true
     IS-EXCEPTION   false
     COST(ms)       0.047237
     RETURN-OBJ     @ArrayList[
                        @Integer[7],
                        @Integer[11],
                        @Integer[2113],
                    ]
    Time fragment[1003] successfully replayed 1 times.