JDK 有很多性能测量工具 JConsole、VisualVM、HPROF 等。它们中的大多数将应用程序作为一个整体进行分析,并且需要一些繁琐的分析过程能到分析出类或方法级别的热点。 当我试图评估我们的一个服务的性能时,可以通过 CPU 火焰图的方法,它在找出代码的 CPU 使用率方面非常有效。 这篇文章记录了我在对投递服务进行基准测试时发现的性能问题,以及通过 CPU 火焰图找到热点方法并改进的调优过程。 要求 如果你使用 IntelliJ IDEA Ultimate ,那么这个 IDE 自带一个火焰图工具 Async Profiler 如果你要在生产环境生成火焰图,你可以借助这个工具 火焰图生成工具 async-profiler 场景 这一切源于一个基准测试。通常我们在交付一个产品前需要对这个服务进行基准测试。并通过基准测试结果得出在某些硬件基准下我们服务的性能指标,最终通过这些指标你可以回答用户提出的容量要求。 投递服务: 这个服务负责从客户端接收消息,放入待发送队列,并持久化到数据库中。然后立即返回给客户端。为了准确额模拟客户端我为此编写了一个基准测试客户端程序。 经过多轮基准测试,我们找到单机服务下了吞吐率最佳的参数,并得到了最佳吞吐率 QPS 769 总计发送 10000 笔业务 50 并发; Welcome to the Notifier CLI 4.8.0 Type 'help' for help. notifier>benchmark -T 123123 -n 10000 -c 50 -w 10 Benchmarking ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ Warm Up 10 Concurrency Level 50 Time taken for tests 13 seconds Complete requests 10000 Failed requests 5000 Refused requests 0 Requests per second 769 [#/sec] Time per request 67 [ms] Percentage of the requests served within a certain time (ms) 50% 46.
Read more本文介绍在 IPv6 网络主机上部署 Docker 主机 IPv6 网络检查 使用 ifconfig 命令查看是否已经配置了 IPv6 网络 $ ifconfig eth1 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.252.248.152 netmask 255.255.255.128 broadcast 10.252.248.255 inet6 2409:8010:5ac0:400:200::2d prefixlen 128 scopeid 0x0<global> inet6 fe80::f816:3eff:fe84:bc36 prefixlen 64 scopeid 0x20<link> ether fa:16:3e:84:bc:36 txqueuelen 1000 (Ethernet) RX packets 7150695 bytes 4751783652 (4.4 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5018420 bytes 4436770306 (4.1 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 你可以看到主机已经获取到了 IPv6 地址 inet6 2409:8010:5ac0:400:200::2d 注意: fe80:: 开头的地址只是链接本地地址 分别在主机和其他主机使用 ping6 命令验证网络是否可达
Read moreLinux 内存相关命令 查看系统内存 # free -h total used free shared buff/cache available Mem: 251G 40G 1.4G 4.0G 209G 206G Swap: 4.0G 3.7G 312M 内存占用 TOP N # ps aux | sort -k4,4nr | head -n 5 200 139348 227 6.9 38668500 18410776 ? Ssl 3月10 1905:49 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-2.el8_3.x86_64/jre/bin/java...org.sonatype.nexus.karaf.NexusMain mysql 33407 1.2 2.2 349722012 6012524 ? Sl 2021 4596:18 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql mysql 118257 0.4 0.5 10170064 1536084 ? Ssl 2月28 66:04 /usr/share/elasticsearch/jdk/bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC root 42564 9.
Read more本文记录 Sonatype Nexus 私服遇到性能劣化问题的分析过程(未解决) 环境说明 使用 sonatype/nexus3 镜像启动,通过挂载卷存储数据 Nexus 配置,可以看到关键配置 -Xms8g -Xmx8g -XX:MaxDirectMemorySize=35158M -XX:+UseConcMarkSweepGC 200 105083 105062 99 11:01 ? 2-00:51:44 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-2.el8_3.x86_64/jre/bin/java -server -Dinstall4j.jvmDir=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-2.el8_3.x86_64/jre -Dexe4j.moduleName=/opt/sonatype/nexus/bin/nexus -XX:+UnlockDiagnosticVMOptions -Dinstall4j.launcherId=245 -Dinstall4j.swt=false -Di4jv=0 -Di4jv=0 -Di4jv=0 -Di4jv=0 -Di4jv=0 -Xms8g -Xmx8g -XX:MaxDirectMemorySize=35158M -XX:ActiveProcessorCount=16 -XX:+UseParNewGC -XX:ParallelGCThreads=12 -XX:MaxTenuringThreshold=6 -XX:SurvivorRatio=5 -XX:+UseConcMarkSweepGC -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -XX:+PrintGCDetails -Xloggc:/nexus-data/vgc/nexus-1646967690.vgc -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=../sonatype-work/nexus3/log/jvm.log -XX:-OmitStackTraceInFastThrow -Djava.net.preferIPv4Stack=true -Dkaraf.home=. -Dkaraf.base=. -Dkaraf.etc=etc/karaf -Djava.util.logging.config.file=etc/karaf/java.util.logging.properties -Dkaraf.data=../sonatype-work/nexus3 -Dkaraf.log=../sonatype-work/nexus3/log -Djava.io.tmpdir=../sonatype-work/nexus3/tmp -Dkaraf.startLocalConsole=false -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=lib/endorsed -Di4j.vpt=true -classpath /opt/sonatype/nexus/.install4j/i4jruntime.jar:/opt/sonatype/nexus/lib/boot/nexus-main.jar:/opt/sonatype/nexus/lib/boot/activation-1.1.1.jar:/opt/sonatype/nexus/lib/boot/jakarta.xml.bind-api-2.3.3.jar:/opt/sonatype/nexus/lib/boot/jaxb-runtime-2.3.3.jar:/opt/sonatype/nexus/lib/boot/txw2-2.3.3.jar:/opt/sonatype/nexus/lib/boot/istack-commons-runtime-3.0.10.jar:/opt/sonatype/nexus/lib/boot/org.apache.karaf.main-4.3.6.jar:/opt/sonatype/nexus/lib/boot/osgi.core-7.0.0.jar:/opt/sonatype/nexus/lib/boot/org.apache.karaf.specs.activator-4.3.6.jar:/opt/sonatype/nexus/lib/boot/org.apache.karaf.diagnostic.boot-4.3.6.jar:/opt/sonatype/nexus/lib/boot/org.apache.karaf.jaas.boot-4.3.6.jar com.install4j.runtime.launcher.UnixLauncher run 9d17dc87 0 0 org.
Read more由于 ksqlDB 在 Kafka 之上运行,我们将使用 Docker Compose 来运行 Kafka 组件、ksqlDB 服务器和 ksqlDB CLI 客户端: Docker 创建文件 ksqldb.yml --- version: '2' services: zookeeper: image: confluentinc/cp-zookeeper:7.0.1 hostname: zookeeper container_name: zookeeper ports: - "2181:2181" environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 broker: image: confluentinc/cp-kafka:7.0.1 hostname: broker container_name: broker depends_on: - zookeeper ports: - "29092:29092" environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181' KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:9092,PLAINTEXT_HOST://localhost:29092 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 ksqldb-server: image: confluentinc/ksqldb-server:0.24.0 hostname: ksqldb-server container_name: ksqldb-server depends_on: - broker ports: - "8088:8088" environment: KSQL_LISTENERS: http://0.
Read moreSpring Data Elasticsearch 从 3.X 迁移到 4.X 因为需要将产品的 spring boot 2.1.6.RELEASE 升级到 2.3.12.RELEASE,升级过程中发现有一些需要迁移的部分,特此整理记录。 本文不是迁移指南,仅仅是工作中遇到的迁移问题笔记 依赖组件 组件 迁移前 迁移后 spring-data-elasticsearch 3.1.9 4.0.9 elasticsearch 6.4.3 7.6.2 GetQuery 已废弃 以下代码中 GetQuery 已经被废弃,并且 getQuery.setId 方法已经被删除 GetQuery getQuery = new GetQuery(); getQuery.setId(globalTxId); GlobalTransactionDocument globalTransaction = this.template .queryForObject(getQuery, GlobalTransactionDocument.class); 使用以下代码替换 Query query = new NativeSearchQueryBuilder().withIds(Collections.singletonList(globalTxId)).build(); SearchHit<GlobalTransactionDocument> result = this.template.searchOne(query, GlobalTransactionDocument.class); GlobalTransactionDocument globalTransaction = result.getContent(); ElasticsearchTemplate 已废弃 使用 ElasticsearchRestTemplate 代替 ElasticsearchTemplate ElasticsearchRestTemplate 索引操作 ElasticsearchTemplate 的 getClient().admin().indices() 用法已经废弃
Read more时间线 时间 5月28-5月31 公办学校点招录取通知 5月30-5月31 填报志愿 志愿填报原则 第三,四批还在摇号的学校是差学校,因为在第一、二批都招不满,所以三,四批不建议填报 批次 一批 全区范围内公办派位学校(第一组) 全朝阳区范围内填报 最有用 二批 全区范围内公办派位学校(第二组) 就近摇号入学和房产对应入学 用来点招挂学籍的学校基本都出这组)这个名字是后改的,以前不这么叫,把这些差学校比较含蓄的叫一般中学,在朝阳区排名倒数30%的学校才叫一般中学,这些学校尽量避免在第一批去选择 三批 公办寄宿初中学校 差学校,摇上了就必须去了 四批 民办初中学校 差学校,摇上了就必须去了 填志愿的时候 别急着第一天就着急填写提交 31号最后一天中午过了再提交也来得及 提交早了 万一有别的录取通知 后悔都麻烦 收到学校邀请填报志愿(除清朝和嘉铭外) 这都不叫通知录取 都是那些没有点招资格 非集团学校的才会用这种方式通知 其目的主要是担心自己招不满人 报自己的人太少 才会使劲宣传 (例如 汇文垂杨柳 17中 日坛实验 工大实验以及个别民办学校等) 第一志愿让报本校:第一志愿是纯摇号(学校希望基数大) 第一志愿让报本校,第二志愿让报自己的集团分校:用没人报也摇不满的差学校接着,用同一法人的集团分校录取后 通过本部游学的方式再调回到本校上课 由于学籍不同单独成班并且每一个孩子都会在教委进行游学备案 这种方式合理合规 第一志愿就让你报集团分校:点招的孩子都走游学方式来本校单独分班(例如陈经纶帝景的2班6班) 点招上会有变动的一些学校 工大附中: 之前都是用工大附双桥来点招孩子 然后调到本校单独成班 也就是之前的13班 都是挑出来的孩子非常强(今年用来挂学籍的工大附双桥分校卖给八十官分了) 八十官分: 这所学校以前就是朝阳区靠前的学校,但是值得注意的是 以前官分集团里的常青藤分校 在卖给北中之前 成绩一直都是朝阳区 前十.原因就是 在2020年以前 官分集团一直都在点招好学生 而且把两个校区的好学生集中在常青藤校区上课. 今年收了工大附双桥以后 相当于点招又回来了 只不过会把好班设在官分上课(咱们群里比如兴隆小学 二外附小等一些小学学校推荐的尖子生 应该在上周六已经参与过学校组织的考试了)这是一所老师管的狠 作业留的多的学校 和陈经纶一个路子 唯一缺的就是好学生 有朝阳前十水准 今年值得关注 会点两个实验班出来 日坛中学和首师实验: 这两所学校 通过学校公众号以及各种新闻 教委官网 包括我在群里也发了不少 大家都能看到咱们区教委对这两个集团学校 给了非常大的支持力度 先后合并了 那么多所学校,今年的日坛中学 必然会点招不少优秀的孩子 毕竟已经去不少小学考试或者要了推荐信息了 这个五月底就能看得到 从今年筛选的范围来看 点四个实验班出来应该问题不大 北京中学: 北京中学合并了传媒 润丰等初中校后 今年的点招人数大大增加了 等于多了好几个可以用来点招挂学籍的学校, 校区 东泽园校区 今年正式开始启用 新初一都会放在这里上课 因此校园容纳量的问题也解决了 未被点招通知的孩子 咱们不牵扯到要填写集团分校 被点招的孩子只有接到学校通知才可以按照学校要求进行填写集团分校 如果未被通知的情况下 看别人这么填 自己也照着写 那可就真的留在最差的没人会报的学校里了 游学班的孩子是需要在教委进行备案的 这种方式合理合规 如果是自己报名进的 即使你成绩再好也没有人敢调你到其他校区 这就是违规了 属于人级分离 没有学校会这么做 校额到校名额 所谓校额到校的意思就是,你这个学校历年来就没有能靠中考成绩考进好高中的,那我政策上给你一个扶贫的支持,你学校年级前几名,虽然中考分数和人家录取分数线差着几十分,也让你直接进好高中。 但是为了不影响人家的高考成绩,既然是扶贫,那这些孩子和考进去的孩子又差着那么多学不到一起,因此就单独分班,成绩不统计入高中平均分,在朝阳区校额到校说白了就是区别对待的
Read more使用 OWASP 依赖检查 Maven 插件 dependency-check-maven 发现依赖漏洞 增加编译插件 在 pom.xml 中增加如下配置,如果是多模块项目请增加在最外层 pom.xml 中,并且配置 <goal> 为 aggregate <properties> <dependency-check-maven.version>6.5.3</dependency-check-maven.version> </properties> <build> <plugins> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>${dependency-check-maven.version}</version> <configuration> <name>notifier-dependency-check</name> <format>HTML</format> <failBuildOnCVSS>9</failBuildOnCVSS> <failOnError>false</failOnError> <skipProvidedScope>true</skipProvidedScope> <skipRuntimeScope>true</skipRuntimeScope> <skipTestScope>true</skipTestScope> <retireJsAnalyzerEnabled>false</retireJsAnalyzerEnabled> <skipArtifactType>pom</skipArtifactType> </configuration> <executions> <execution> <goals> <goal>aggregate</goal> </goals> </execution> </executions> </plugin> </plugins> </build> failBuildOnCVSS 当发现此级别的漏洞后编译失败,评分和严重等级如下 0.0 None 0.1 – 3.9 Low 4.0 – 6.9 Medium 7.0 – 8.9 High 9.0 – 10.0 Critical failOnError 发现 CVSS 评分大于等于 9 时编译失败
Read more由于 Docker Desktop 修改了授权条款,不再对企业用户免费,所以我们需要啊寻求一种替代品。到目前为止 Minikube 已经成为 Docker Desktop 最简单的替代品。 Minikube 用于在本地环境中运行 Kubernetes 集群,但它也运行了一个可用于运行容器的 Docker 守护进程。如果你不需要使用 Kubernetes ,那么你可以通过 minikube pause 暂停 Kubernetes 相关镜像,从而解决系统资源。 在 macOS 上,Minikube 运行在很多虚拟化技术上,由于ISSUE-6296原因,本例使用 Virtualbox 方式(你需要先安装 Virtualbox)。 卸载 Docker Desktop for macOS 如果你之前安装过 Docker Desktop,那么你需要先卸载它 在 Docker Desktop 菜单中选择 Troubleshoot 并且选择 Uninstall. 删除 /Applications/Docker.app 安装 Docker CLI 因为卸载 Docker Desktop 后将自动卸载 Docker CLI,所以你需要单独安装 $ brew install docker $ brew install docker-compose 提示: 在执行 brew install docker-compose 命令的时候可能得到如下的失败信息,这是因为依赖包下载失败。你可以使用 brew install gdbm 单独下载依赖包,就避免了找不到依赖版本的错误。
Read more常用 Kubectl 命令 创建命名空间 新建一个名为 nc-namespace.yaml 的 YAML 文件 apiVersion: v1 kind: Namespace metadata: name: nc-namespace 然后运行以下命令创建命名空间 $ kubectl create -f nc-namespace.yaml namespace/nc-namespace created 创建命名空间资源配额文件 新建一个名为 nc-quota.yaml 的 YAML 文件 apiVersion: v1 kind: ResourceQuota metadata: name: nc-quota namespace: nc-namespace spec: hard: pods: "10" requests.cpu: "2" requests.memory: 2Gi limits.cpu: "4" limits.memory: 4Gi 然后运行以下命令创建资源配额 $ kubectl create -f nc-quota.yaml resourcequota/nc-quota created 创建 PV 卷和 PVC 新建一个名为 nc-pv.yaml 的 YAML 文件 apiVersion: v1 kind: PersistentVolume metadata: name: nc-pv-volume namespace: nc-namespace spec: storageClassName: manual capacity: storage: 5Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nc-pv-claim namespace: nc-namespace spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 5Gi 然后运行以下命令创建卷
Read more