首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

小诺快速开发平台文档细化重构

转眼做开源已经过去三个月之久,通过每天跟跟其他小伙伴们的接触,也发现小诺框架有很多需要补充及修改的内容,同时也收到部分小伙伴的打赏金,这也使得我们小诺更有信心的持续发展下去的一部分。当初做开源的唯一目的也是为了全国各地广交朋友,并且做好一款自己使用,别的小伙伴及企业使用的脚手架轮子。 在此期间,我们也大量的接受使用者私聊问题处理,并且远程解决了很多由于操作引起的环境及调试问题,坚持做好脚手架的同时,服务为重才是小诺的核心,在精力能及的范围内让更多的初学者得到更好更有效的技术支持,也正好是我们小诺的初衷! 2020年3月1日我们发布了v1.3版本,在这个阶段代码生成也是作为一款脚手架不可缺少的功能,已实现每个字段的作用域配置,低代码化,在第三阶段完成主外键关联等相关生成模式。 同时,文档方面也使用了新的主题素材由 reco_luan作者提供的vuepress-theme-reco主题进一步打造了新的更细化的文档平台提供给各位开发者阅读理解小诺 此版本我们加入了基础篇文档,由于长时间发现部分初学者小伙伴对基础支撑有点不太理解,我们加入了最基础的jdk安装教程、maven安装教程、nodejs安装教程、idea导入小诺项目、lombok插件安装教程,相信此次更新的基础篇能帮助更多的初学者小伙伴运行使用小诺。

优秀的个人博客,低调大师

SkyWalking链路监控(一):SkyWalking快速搭建

简介 当分布式系统服务比较多,特别是微服务,出现故障就很难排查。所以需要借助APM 系统进行排查(Application Performance Management,即应用性能管理),SkyWalking是APM 系统的一种,类似的产品还有CAT、Zipkin、Pinpoint。 SkyWalking和Pinpoint相比其他系统,做到了无侵入性。Pinpoint出现的时间长,文档也较为丰富,为多数公司使用。 国人开源的APM产品SkyWalking,探针采集数据粒度相较于 Pinpoint 来说略粗,但性能表现优秀。于2019年进入到Apache 基金会的孵化器毕业成为顶级项目;实属后起之秀,本文推荐使用SkyWalking。 搭建SkyWalking 下载SkyWalking 从官网下载SkyWalking APM,选择对应的版本。 下载之后解压即可。 配置数据库 Skywalking支持h2、mysql、ElasticSearch作为数据存储,官方推荐使用ElasticSearch。 根据具体业务,这里使用最方便的h2数据库做数据存储。h2是Skywalking自带的,为一种内存数据库。内存数据会因为服务故障、重启而丢失,并不适合长时间监控的场景,所以需要将其更改为文件数据库。 打开apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\config\application.yml文件,修改h2节点的url地址。 url: ${SW_STORAGE_H2_URL:jdbc:h2:tcp://127.0.0.1/~/skywalking-oap-db;AUTO_SERVER=TRUE} 启动 h2 TCP h2文件数据库需要启动 h2 TCP,否则Skywalking会因为监听不到9092端口而启动失败。 linux启动 h2 TCP 的方式: 新建启动脚本,运行即可,启动后就会在用户目录下(如administrator或root或home/user等用户目录)自动创建数据库文件skywalking-oap-db。 linux脚本如下 #!/usr/bin/env sh PRG="$0" PRGDIR=`dirname "$PRG"` [ -z "$OAP_HOME" ] && OAP_HOME=`cd "$PRGDIR/.." >/dev/null; pwd` OAP_LOG_DIR="${OAP_HOME}/logs" JAVA_OPTS=" -Xms64M -Xmx256M" if [ ! -d "${OAP_HOME}/logs" ]; then mkdir -p "${OAP_LOG_DIR}" fi _RUNJAVA=${JAVA_HOME}/bin/java [ -z "$JAVA_HOME" ] && _RUNJAVA=java CLASSPATH="$OAP_HOME/config:$CLASSPATH" for i in "$OAP_HOME"/oap-libs/h2*.jar do CLASSPATH="$i:$CLASSPATH" done OAP_OPTIONS=" -Doap.logDir=${OAP_LOG_DIR}" # 如果需要远程连接h2数据库,需将-tcp改为-tcpAllowOthers eval exec "\\"$_RUNJAVA\\" ${JAVA_OPTS} ${OAP_OPTIONS} -classpath $CLASSPATH org.h2.tools.Server -tcp \\ 2>${OAP_LOG_DIR}/h2Tcp.log 1> /dev/null &" if [ $? -eq 0 ]; then sleep 1 echo "SkyWalking h2Tcp started successfully!" else echo "SkyWalking h2Tcp started failure!" exit 1 fi windows启动 h2 TCP 的方式: 新建启动脚本,运行即可。windows脚本如下 @REM 如果需要远程查看h2数据库(tcp端口9092,页面访问端口8082),需将-tcp改为-tcpAllowOthers @echo off setlocal set OAP_PROCESS_TITLE=Skywalking-H2TcpServer set OAP_HOME=%~dp0%.. set OAP_OPTS="-Xms64M -Xmx256M -Doap.logDir=%OAP_HOME%\\logs" set CLASSPATH=%OAP_HOME%\\config;.; set CLASSPATH=%OAP_HOME%\\oap-libs\\*;%CLASSPATH% if defined JAVA_HOME ( set _EXECJAVA="%JAVA_HOME%\\bin\\java" ) if not defined JAVA_HOME ( echo "JAVA_HOME not set." set _EXECJAVA=java ) start "%OAP_PROCESS_TITLE%" %_EXECJAVA% "%OAP_OPTS%" -cp "%CLASSPATH%" org.h2.tools.Server -tcp endlocal 设置Java Agent Java Agent为Java探针,是java命令的一个参数。虚拟机启动的时候,在执行main方法前,会先找到javaagent 命令指定 jar 包,执行premain-class中的preman()方法。 设置方式如下: 复制apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent文件到监控目标服务器上,然后在启动命令中添加参数: windows参数如下: set SW_AGENT_NAME=eda-app-base-service set SW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.0.24:11800 set JAVA_TOOL_OPTIONS=-javaagent:E:\\tech\\agent\\skywalking-agent.jar SW_AGENT_NAME:设置服务名称 SW_AGENT_COLLECTOR_BACKEND_SERVICES:后端的 collector 端口及地址,设置为SkyWalking服务器IP:11800(默认端口) JAVA_TOOL_OPTIONS:agent文件夹下skywalking-agent.jar位置 Linux参数如下: # SkyWalking Agent 配置 export SW_AGENT_NAME=demo-application # 配置 Agent 名字。一般来说,我们直接使用 Spring Boot 项目的 `spring.application.name` 。 export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 # 配置 Collector 地址。 export SW_AGENT_SPAN_LIMIT=2000 # 配置链路的最大 Span 数量。一般情况下,不需要配置,默认为 300 。主要考虑,有些新上 SkyWalking Agent 的项目,代码可能比较糟糕。 export JAVA_AGENT=-javaagent:/Users/yunai/skywalking/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar # SkyWalking Agent jar 地址。 # Jar 启动 java -jar $JAVA_AGENT -jar lab-39-demo-2.2.2.RELEASE.jar 具体变量可能因版本有所变化(本文版本为8.4.0),更多变量可在agent\config\agent.config查看。 启动运行 首先启动 h2 TCP 启动apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\bin\startup.bat,它会同时启动Skywalking-Webapp、Skywalking-Collector两个服务。 启动业务服务 访问http://127.0.0.1:8080,即可看到SkyWalking界面 如果8080端口被占用,可以通过apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\webapp\webapp.yml文件修改端口。 文章内容参考: Skywalking的存储配置与调优:https://blog.csdn.net/smooth00/article/details/96479544

优秀的个人博客,低调大师

MySQL中怎样快速找出超长索引

大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 需求: 想要查找哪些索引太长了,这个SQL在5.7下跑的特别慢,8.0则挺快的,帮看下有啥优化方案没 具体SQL 和执行计划如下: SELECT c.TABLE_SCHEMA AS DB, c .TABLE_NAME AS TBL, c.COLUMN_NAME AS COL, c.CHARACTER_OCTET_LENGTH AS COL_LEN_BYTES, s.INDEX_NAME, s.SUB_PART * CHARACTER_OCTET_LENGTH/CHARACTER_MAXIMUM_LENGTH AS SUB_PART_LENFROM information_schema.COLUMNS c INNER JOIN information_schema.STATISTICS s USING(TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)INNER JOIN information_schema.TABLES t USING(TABLE_SCHEMA, TABLE_NAME) WHERE c.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test')AND c.DATA_TYPE IN ("varchar", "char", "text", "blob") AND ((CHARACTER_OCTET_LENGTH > 50 and SUB_PART is null) orSUB_PART * CHARACTER_OCTET_LENGTH/CHARACTER_MAXIMUM_LENGTH > 50)AND t.TABLE_ROWS > 10000ORDER BY COL_LEN_BYTES DESC;执行计划*************************** 1. row *************************** id: 1 select_type: SIMPLE table: c partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases; Using temporary; Using filesort*************************** 2. row *************************** id: 1 select_type: SIMPLE table: s partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases; Using join buffer (Block Nested Loop)*************************** 3. row *************************** id: 1 select_type: SIMPLE table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases; Using join buffer (Block Nested Loop)3 rows in set, 1 warning (0.01 sec)select count(*) from information_schema.tables;+----------+| count(*) |+----------+| 33600 |+----------+select count(*) from information_schema.COLUMNS;+----------+| count(*) |+----------+| 342967 |+----------+select count(*) from information_schema.STATISTICS;+----------+| count(*) |+----------+| 135167 |+----------+ 上面的SQL 运行450+ s 也运行不出来,最后kill掉了。 我们初步分析一下,从执行计划中 可以看出三个表都是ALL所以很慢 那添加索引不就行了吗,因为是系统表,所以不能随便添加! 那该怎么办?想到了AUTOKEY 就是临时索引,那思路就是改写SQL 达到生成临时索引,最终达到优化效果 改写的SQL 如下 SELECT c.TABLE_SCHEMA AS DB, c.TABLE_NAME AS TBL, c.COLUMN_NAME AS COL, c.CHARACTER_OCTET_LENGTH AS COL_LEN_BYTES, s.INDEX_NAME,s.SUB_PART * c.CHARACTER_OCTET_LENGTH/c.CHARACTER_MAXIMUM_LENGTH AS SUB_PART_LENFROM ( select c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME ,c.CHARACTER_OCTET_LENGTH ,c.CHARACTER_MAXIMUM_LENGTH , c.DATA_TYPEfrom information_schema.COLUMNS c WHERE c.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND c.DATA_TYPE IN ("varchar", "char", "text", "blob") limit 10000000000) c INNER JOIN (select s.TABLE_SCHEMA, s.TABLE_NAME, s.COLUMN_NAME ,s.SUB_PART,s.INDEX_NAMEfrom information_schema.STATISTICS s WHERE s.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test')limit 10000000000 )s USING(TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)INNER JOIN information_schema.TABLES t USING(TABLE_SCHEMA, TABLE_NAME) WHERE c.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND c.DATA_TYPE IN ("varchar", "char", "text", "blob") AND ((c.CHARACTER_OCTET_LENGTH > 50 and s.SUB_PART is null) ors.SUB_PART * c.CHARACTER_OCTET_LENGTH/c.CHARACTER_MAXIMUM_LENGTH > 50)AND t.TABLE_ROWS > 10000ORDER BY COL_LEN_BYTES DESC;*************************** 1. row *************************** id: 1 select_type: PRIMARY table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases; Using temporary; Using filesort*************************** 2. row *************************** id: 1 select_type: PRIMARY table: <derived2> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 388 ref: information_schema.t.TABLE_SCHEMA,information_schema.t.TABLE_NAME rows: 2 filtered: 50.00 Extra: Using where*************************** 3. row *************************** id: 1 select_type: PRIMARY table: <derived3> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 582 ref: information_schema.t.TABLE_SCHEMA,information_schema.t.TABLE_NAME,c.COLUMN_NAME rows: 2 filtered: 100.00 Extra: Using where*************************** 4. row *************************** id: 3 select_type: DERIVED table: s partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases*************************** 5. row *************************** id: 2 select_type: DERIVED table: c partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases5 rows in set, 1 warning (0.01 sec) 结果来了 2463 rows in set, 417 warnings (23.39 sec) 但是经过几次运行之后 有时候是40多秒有时候甚至达到了166s 非常不稳定! 那分析下上面这个SQL的问题在哪里? 问题就是生成的AUTO KEY的量相对来说非常大!因为没有进行任何过滤 那现在的思路就是对生成的AUTOKEY的量 进行减少 我们通过相对小的表TABLES表生成autokey 之后STATISTICS ,COLUMNS 表分别跟 TABLES 表进行JOIN 然后减少数据量 达到减少生成AUOKEY 的量 减少 达到优化目的 ,具体的方法如下 select count(1) from (select s.TABLE_SCHEMA, s.TABLE_NAME, s.COLUMN_NAME ,s.SUB_PART,s.INDEX_NAMEfrom information_schema.STATISTICS s WHERE s.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') )s straight_join (select t.TABLE_SCHEMA, t.TABLE_NAMEfrom information_schema.TABLES t WHERE t.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND t.TABLE_ROWS > 10000limit 10000000000) t on s.TABLE_SCHEMA=t.TABLE_SCHEMA and s.TABLE_NAME =t.TABLE_NAME*************************** 1. row *************************** id: 1 select_type: PRIMARY table: s partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases*************************** 2. row *************************** id: 1 select_type: PRIMARY table: <derived3> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 388 ref: information_schema.s.TABLE_SCHEMA,information_schema.s.TABLE_NAME rows: 2 filtered: 100.00 Extra: Using index*************************** 3. row *************************** id: 3 select_type: DERIVED table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases3 rows in set, 1 warning (0.00 sec)+----------+| count(1) |+----------+| 7478 |+----------+1 row in set, 40 warnings (7.52 sec)select count(1) from ( select c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME ,c.CHARACTER_OCTET_LENGTH ,c.CHARACTER_MAXIMUM_LENGTH , c.DATA_TYPEfrom information_schema.COLUMNS c WHERE c.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND c.DATA_TYPE IN ("varchar", "char", "text", "blob") ) c straight_join (select t.TABLE_SCHEMA, t.TABLE_NAMEfrom information_schema.TABLES t WHERE t.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND t.TABLE_ROWS > 10000limit 10000000000) t on c.TABLE_SCHEMA=t.TABLE_SCHEMA and c.TABLE_NAME =t.TABLE_NAME*************************** 1. row *************************** id: 1 select_type: PRIMARY table: c partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases*************************** 2. row *************************** id: 1 select_type: PRIMARY table: <derived3> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 388 ref: information_schema.c.TABLE_SCHEMA,information_schema.c.TABLE_NAME rows: 2 filtered: 100.00 Extra: Using index*************************** 3. row *************************** id: 3 select_type: DERIVED table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases3 rows in set, 1 warning (0.00 sec)+----------+| count(1) |+----------+| 8106 |+----------+1 row in set, 417 warnings (8.62 sec) 最终SQL 如下 SELECT c.TABLE_SCHEMA AS DB, c.TABLE_NAME AS TBL, c.COLUMN_NAME AS COL, c.CHARACTER_OCTET_LENGTH AS COL_LEN_BYTES, s.INDEX_NAME,s.SUB_PART * c.CHARACTER_OCTET_LENGTH/c.CHARACTER_MAXIMUM_LENGTH AS SUB_PART_LENfrom ( select c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME ,c.CHARACTER_OCTET_LENGTH ,c.CHARACTER_MAXIMUM_LENGTH , c.DATA_TYPEfrom information_schema.COLUMNS c WHERE c.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND c.DATA_TYPE IN ("varchar", "char", "text", "blob") ) c straight_join (select t.TABLE_SCHEMA, t.TABLE_NAMEfrom information_schema.TABLES t WHERE t.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND t.TABLE_ROWS > 10000limit 10000000000) t on c.TABLE_SCHEMA=t.TABLE_SCHEMA and c.TABLE_NAME =t.TABLE_NAMEstraight_join(select s.* from (select s.TABLE_SCHEMA, s.TABLE_NAME, s.COLUMN_NAME ,s.SUB_PART,s.INDEX_NAMEfrom information_schema.STATISTICS s WHERE s.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') )s straight_join (select t.TABLE_SCHEMA, t.TABLE_NAMEfrom information_schema.TABLES t WHERE t.TABLE_SCHEMA not in ('information_schema','performance_schema','mysql','sys', 'test') AND t.TABLE_ROWS > 10000limit 10000000000) t on s.TABLE_SCHEMA=t.TABLE_SCHEMA and s.TABLE_NAME =t.TABLE_NAMElimit 10000000000) s on c.TABLE_SCHEMA=s.TABLE_SCHEMA and c.TABLE_NAME=s.TABLE_NAME and c.COLUMN_NAME =s.COLUMN_NAMEwhere ((c.CHARACTER_OCTET_LENGTH > 50 and s.SUB_PART is null) ors.SUB_PART * c.CHARACTER_OCTET_LENGTH/c.CHARACTER_MAXIMUM_LENGTH > 50)*************************** 1. row *************************** id: 1 select_type: PRIMARY table: c partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases*************************** 2. row *************************** id: 1 select_type: PRIMARY table: <derived3> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 388 ref: information_schema.c.TABLE_SCHEMA,information_schema.c.TABLE_NAME rows: 2 filtered: 100.00 Extra: Using index*************************** 3. row *************************** id: 1 select_type: PRIMARY table: <derived4> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 582 ref: information_schema.c.TABLE_SCHEMA,information_schema.c.TABLE_NAME,information_schema.c.COLUMN_NAME rows: 2 filtered: 100.00 Extra: Using where*************************** 4. row *************************** id: 4 select_type: DERIVED table: s partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_frm_only; Scanned all databases*************************** 5. row *************************** id: 4 select_type: DERIVED table: <derived6> partitions: NULL type: refpossible_keys: <auto_key0> key: <auto_key0> key_len: 388 ref: information_schema.s.TABLE_SCHEMA,information_schema.s.TABLE_NAME rows: 2 filtered: 100.00 Extra: Using index*************************** 6. row *************************** id: 6 select_type: DERIVED table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases*************************** 7. row *************************** id: 3 select_type: DERIVED table: t partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned all databases7 rows in set, 1 warning (0.00 sec) 看起来稳定了,跑了几次,都没超过15秒 我的新一轮的SQL 优化课 即将在春节后开课 我是知数堂SQL 优化班老师~ ^^ 如有关于SQL优化方面疑问和一起交流的请加 并且 @兔子@知数堂SQL优化 高性能MySQL,SQL优化群 有叶金荣,吴炳锡 两位大神坐镇 :579036588 欢迎加入 知数堂大家庭。 我的微信公众号:SQL开发与优化(sqlturning) 扫码直达宝藏课程 本文分享自微信公众号 - 老叶茶馆(iMySQL_WX)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

5G推动智慧医疗快速发展

近日,国家工信部和卫健委办公厅联合组织开展“5G+医疗健康”应用试点项目申报工作,围绕急诊救治、远程诊断、远程治疗、远程重症监护(ICU)、中医诊疗、医院管理、智能疾控、健康管理等8个重点方向,鼓励各地、各单位创新5G应用场景,加速卫生健康网络基础设施改造,推动5G+智慧医疗创新发展,引发高度关注。 近年来,我国医疗领域问题不断凸显,一方面医疗人力和设备资源有限且区域分布不均衡,不少人面临着“看病难、看病贵、看病慢”等困扰;另一方面,现有医疗技术水平、效率和服务也不高,医院运营成本压力较大。在此背景下,为满足行业发展需求,智慧医疗成为破局的关键所在,而5G的出现则为智慧医疗带来了催化作用。 凭借高速率、低延迟、大容量的显著特点,5G网络能够深入到医疗诊治和医院管理的各个环节,提升医疗水平,增强医院管理,同时与人工智能、VR/AR、机器人等智能技术和装备相结合,协作医生与管理人员,减轻治疗和作业压力。除此以外,5G还能通过医疗服务的信息化、移动化和远程化,加速医疗资源的共享与下沉。 总而言之,5G的出现与应用能催化智慧医疗的进一步发展。目前,根据工信部最新数据透露,我国5G基站建设已经突破60万座,提前完成全年建设目标。同时5G网络覆盖也已取得不错成果,5G用户累计突破1亿人次,国内5G商用进程已是初具成效。在此背景下,未来伴随试点应用的不断开展,5G与医疗融合将真正成熟。 不过,在此之前,我国也还需要克服三方面的困难:其一是加快5G基站建设,完善5G专用网络覆盖,降低5G应用成本与价格;其二是加速5G技术研究,提升5G技术应用的安全性和可靠性;其三是强化行业标准与监管,为行业应用营造健康、有序环境。只有解决了网络、技术和标准三方面难题,发展才能最终取得理想结果。

优秀的个人博客,低调大师

XiaoNuo 快速开发平台代码生成发布啦

小诺团队做开源已经将近一个月,在平时忙碌的工作之余跟晚上的时间,也在抓紧时间做开发。 在此时间段当然我们的其他产品也不能停下来,就好比:xiaonuo-layui版本的工作流大模块、xiaonuo-cloud版本,相信很快跟小伙伴们见面。 为了加快cloud版本日程,小诺团队成员也由2人增加到3人!同时也欢迎其他有想法的小伙伴加入到我们的开源中一起做贡献,可以在官网获取联系方式与我们沟通! 此次一共发布了xiaonuo-vue版本与xiaonuo-layui版本的代码生成器,完全独立的模块,可拓展,可二次开发,为普通模块开发省去了大部分拷贝粘贴的时间。 可生成所有查询框、查询条件根据不同的需求进行删减,下个版本会在此基础上面增加详细到每个字段在各个代码模块下的配置 感兴趣的小伙伴可以关注下我们,全系版本都免费,我们的官网是:https://xiaonuo.vip

优秀的个人博客,低调大师

Jest 单元测试快速上手指南

技术交流群: https://fiora.suisuijiang.com/原文链接: https://github.com/yinxin630/blog/issues/38 Jest[1] 是一款简单, 容易上手且功能十分强大的测试框架 安装 yarn add -D jest 使用 创建 test 目录, 添加 plus.spec.js 文件 describe('example',()=>{it('shouldequal2',()=>{expect(1+1).toBe(2);});}); 执行 yarn jest 或者 yarn jest test/plus.spec.js 运行测试用例 成功结果 失败结果 输出测试覆盖率 在根目录创建 jest.config.js 配置文件 module.exports={collectCoverage:true,}; 创建 plus.js 模块 module.exports=functionplus(a,b){returna+b;} 修改测试用例使用模块 constplus=require('../plus');describe('example',()=>{it('shouldequal2',()=>{expect(plus(1,1)).toBe(2);});}); 再次执行测试, 输出覆盖率如下 在浏览器中打开 coverage/lcov-report/index.html 可以浏览覆盖率结果页面 忽略部分文件或者代码行的覆盖率 修改 plus.ts 模块, 添加更多分支 exportdefaultfunctionplus(a:number,b:number){if(a+b>100){return0;}elseif(a+b<0){return0;}else{returna+b;}} 重新执行测试, 覆盖率输出结果 你可以完善测试用例, 或者可能有些文件(譬如 config)和代码分支并不需要测试, 可以将其在测试覆盖率结果中排除, 参考如下配置 忽略目录下所有文件 在 jest.config.js 中添加 collectCoverageFrom:['**/*.{ts,tsx}','!**/node_modules/**','!**/[directorypath]/**',], 以 ! 开头的表示忽略与其匹配的文件 忽略单个文件 在该文件顶部添加 /* istanbul ignore file */ 忽略一个函数, 一块分支逻辑或者一行代码 在该函数, 分支逻辑或者代码行的上一行添加 /* istanbul ignore next */ 支持 Typescript 执行 yarn add -D typescript ts-jest @types/jest 安装 typescript 和声明 并在 jest.config.js 中添加 preset: 'ts-jest' 将 plus.js 重命名为 plus.ts exportdefaultfunctionplus(a:number,b:number){returna+b;} 同样的, 将 plus.spec.js 重命名为 plus.spec.ts importplusfrom'../plus'describe('example',()=>{it('shouldequal2',()=>{expect(plus(1,1)).toBe(2);});}); 执行测试, 结果和之前一致 执行单测时不校验 ts 类型 有时你可能会希望不校验 ts 类型, 仅执行代码测试, 比如需要在 CI 中将类型校验和单元测试分为两个任务 在 jest.config.js 中添加如下内容 globals:{'ts-jest':{isolatedModules:true,},} 测试 React 组件 安装 react 依赖 yarn add react react-dom 和声明 yarn add -D @types/react安装 react 测试库 yarn add -D @testing-library/react @testing-library/jest-dom 添加 typescript 配置文件 tsconfig.json {"compilerOptions":{"target":"es2018","strict":true,"moduleResolution":"node","jsx":"react","allowSyntheticDefaultImports":true,"esModuleInterop":true,"lib":["es2015","es2016","es2017","dom"]},"exclude":["node_modules"]} 新增测试组件 Title.tsx import React from 'react';function Title() { return ( <h1>Title</h1> );}export default Title; 新增测试用例 test/Title.spec.tsx /** * @jest-environment jsdom */import React from 'react';import { render } from '@testing-library/react';import '@testing-library/jest-dom/extend-expect';import Title from '../Title';describe('Title', () => { it('should render without error', () => { const { getByText } = render(<Title />); const $title = getByText('Title'); expect($title).toBeInTheDocument(); });}); 执行 yarn jest test/Title.spec.ts 查看结果 处理静态资源引用 react 组件有时引用一些静态资源, 譬如图片或者 css 样式表, webpack 会正确的处理这些资源, 但是对 Jest 来讲, 这些资源是无法识别的 创建 Title.less 样式表 h1 { color: red;} 修改 Ttitle.tsx, 添加样式引用 import './Title.less'; 执行测试会报错 我们需要配置 transform 对其处理 在根目录创建 jest.transformer.js constpath=require('path');module.exports={process(src,filename){return`module.exports=${JSON.stringify(path.basename(filename))};`;},}; 这里是将资源文件名作为模块导出内容 修改 jest.config.js 添加如下配置 transform:{'\\.(less)$':'<rootDir>/jest.transformer.js',//正则匹配,处理less样式}, 然后重新执行测试就可以了 处理 css in js 如果你使用了类似 linaria[2] 这种 css in js 方案, 其中的 css 样式模板字符串是不支持运行时编译的 修改 Title.tsx import React from 'react';import { css } from 'linaria';const title = css` color: red;`;function Title() { return <h1 className={title}>Title</h1>;}export default Title; 运行测试会报错 linaria 是通过 babel 插件将其预编译为 class 名的, 这里可以 mock 一下 css 函数, 返回一个随机值作为 class 名 在根目录创建 jest.setup.js jest.mock('linaria',()=>({css:jest.fn(()=>Math.floor(Math.random()*(10**9)).toString(36)),})); 修改 jest.config.js 添加如下配置 setupFilesAfterEnv:['./jest.setup.js'], 重新执行测试就可以了 测试交互事件 新增 Count.tsx 组件 import React, { useState } from 'react';function Count() { const [count, updateCount] = useState(0); return ( <div> <span data-testid="count">{count}</span> <button data-testid="button" onClick={() => updateCount(count + 1)}> +1 </button> </div> );}export default Count; 新增 test/Count.spec.tsx 组件 /** * @jest-environment jsdom */import React from 'react';import { render, fireEvent } from '@testing-library/react';import '@testing-library/jest-dom/extend-expect';import Count from '../Count';describe('Count', () => { it('should render without error', () => { const { getByTestId } = render(<Count />); const $count = getByTestId('count'); const $button = getByTestId('button'); expect($count).toHaveTextContent('0'); fireEvent.click($button); expect($count).toHaveTextContent('1'); });}); 这里通过 testId 来查找元素, 使用 fireEvent[3] 触发 click 事件 测试函数调用 新增 Button.tsx 组件 import React from 'react';type Props = { onClick: () => void;};function Button({ onClick }: Props) { return <button onClick={onClick}>button</button>;}export default Button; 添加 test/Button.spec.tsx 测试用例 /** * @jest-environment jsdom */import React from 'react';import { render, fireEvent } from '@testing-library/react';import '@testing-library/jest-dom/extend-expect';import Button from '../Button';describe('Button', () => { it('should render without error', () => { const handleClick = jest.fn(); // mock 函数 const { getByText } = render(<Button onClick={handleClick} />); // 传递 props const $button = getByText('button'); fireEvent.click($button); expect(handleClick).toHaveBeenCalled(); // 期望其被调用 });}); 测试包含定时器的逻辑 //timer.tsletcache='cache';exportdefaultfunctiontimer(){setTimeout(()=>{cache='';},1000);returncache;} //test/timer.spec.tsimporttimerfrom'../timer'jest.useFakeTimers();//替代原生计时器describe('timer',()=>{it('shouldclearcacheaftertimerout',()=>{expect(timer()).toBe('cache');jest.advanceTimersByTime(1000);//让计时器前进1000msexpect(timer()).toBe('');})}) mock 依赖模块 要测试的模块可能依赖于其他模块或者第三方 npm 包的结果, 我们可以使用 Mock Functions[4] 对其进行 mock //test/mock.spec.tsimport{mocked}from'ts-jest/utils';importplusfrom'../plus';jest.mock('../plus');describe('mock',()=>{it('shouldreturnmockvalue',()=>{mocked(plus).(50);expect(plus(1,1)).toBe(50);});}); 还有官网 mock axios npm 模块的例子 https://jestjs.io/docs/en/mock-functions#mocking-modules mock 环境变量和命令行参数 有的模块会从环境变量和命令行参数取值, 并且可能是在模块初始化时获取的 //process.tsconst{env,argv}=process;exportfunctiongetEnvironmentValue(){returnenv.Value;}exportfunctiongetProcessArgsValues(){returnargv[2];} 这种情况我们需要在每个测试用例中, 使用动态 require 来运行时引入改模块, 并且设置其每次引入时删除 cache //test/process.spec.tsdescribe('mockprocess',()=>{beforeEach(()=>{jest.resetModules();});it('shouldreturnenvironmentvalue',()=>{process.env={Value:'value',};const{getEnvironmentValue}=require('../process');expect(getEnvironmentValue()).toBe('value');});it('shouldreturnprocessargsvalue',()=>{process.argv=['value'];const{getProcessArgsValues}=require('../process');expect(getProcessArgsValues()).toBe('value');});}); 参考资料 [1]Jest: https://jestjs.io/ [2]linaria: https://github.com/yinxin630/blog/issues/36 [3]fireEvent: https://testing-library.com/docs/dom-testing-library/api-events [4]Mock Functions: https://jestjs.io/docs/en/mock-function-api 本文分享自微信公众号 - 牧码的星星(gh_0d71d9e8b1c3)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

使用 minikube 快速上手 Kubernetes | v1.7.3

minikube 踩坑和填坑。 环境说明 宿主机的环境 操作系统:Windows 10 虚拟化:VirtualBox 6.0 说明:在 Win 10 系统里尝试过 Hyper-V,感觉不好用,所以还是回归到了 VirtualBox。如果你用的是 Hyper-V,或者是 MacOS/Linux 操作系统,中间部分流程应该也可以参考。 如果有疑问可以查看 官方文档。 版本 Minikube:1.7.3 Kubernetes:1.17.3 说明:目前(2020-03-15)minikube 最新的版本是 1.8.2。我前几天尝试的版本是 1.8.1,踩到了其中的大 bug。 从 1.8.0 版本开始,它在部署的时候需要下载一个 Preload tarball images 的镜像文件,大小有 500 MB。 这个文件安装过程中是先下载到 .minikube\cache\preloaded-tarball 目录中,并且支持断点续传。但是,当我把从其它地方下载完全的文件放到该目录中时,并没有效果。也就是说缓存实际上没用。 最新的 1.8.2 似乎修复了这个 bug。 Minikube 最新的 1.8.2 和 1.7.3 对应的 Kubernetes 版本都是 1.17.3。使用旧版本启动集群需要额外下载的软件大小是这个 preload image 的一半,而且鉴于这个功能现在还貌似不够稳定,所以 推荐 使用 1.7.3 版本的 minikube。 下载 使用 minikube 安装部署所需要下载(拉取)的东西分为以下几类: minikube 命令:从 GitHub 上下载 minikube 启动虚机所需 iso:安装过程中自动下载,通过配置 --iso-url 加速,会缓存到本地 kubernetes 集群部署所需镜像,安装过程中自动拉取,通过配置 --image-repository 加速 kubernetes 集群部署所需程序,安装过程中自动下载,没有配置项,但是会缓存到本地 kubernetes 宿主机(即 Windows)所需客户端程序,安装过程自动下载,没有配置项,但是会缓存 应用所需镜像:安装过程不涉及,但是可以通过 --registry-mirror 指定加速镜像 可缓存的文件 整理了可缓存下载的文件如下,它们在 minikube 部署集群的时候会自动下载,如果下载时间过长,可以考虑通过其它下载工具提前下载,保存到指定目录(具体下文会说到)。 kubectl.exe ,下载地址 这是 Windows 系统下的 kubectl 客户端程序,启动 dashboard 时需要。 不管是通过 minikube 哪个版本安装,这个文件都是必需的。 kubeadm, 下载地址 kubectl, 下载地址 kubelet, 下载地址 这是 Linux 系统下的程序,虚拟机内安装 Kubernetes 需要。1.7.3 的 minikube 需要分别下载。 preloaded-images-k8s-v1-v1.17.3-docker-overlay2.tar.lz4, 下载地址 这是 1.8.0 之后的 minikube 需要下载的文件 以上文件下载无需科学上网,但是要看情况,出现无法连接可以多试几次。 安装 minikube minikube 就是单个 .exe 文件,既可以直接下载 minikube-windows-amd64.exe 然后改名,也可以下载 minikube-installer.exe 安装。推荐后者,因为安装包的体积更小,而且使用更方便。 执行 minikube-installer.exe,这个安装过程非常简单。 默认安装路径是 C:\Program Files\Kubernetes\Minikube,安装程序会自动把该路径加入到 PATH 中。 运行 cmd 命令行,检查 minikube 的版本: > minikube version minikube version: v1.7.3 commit: 436667c819c324e35d7e839f8116b968a2d0a3ff 启动集群 注意:如果以前安装过,需要使用 minikube delete 命令把旧版本删除。 如果版本不一致或者出现莫名其妙的错误,可以把 C:\Users\你的用户名\.minikube 也删除。 minikube v1.7.3 执行: minikube start --vm-driver=virtualbox --image-mirror-country=cn --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.7.3.iso --registry-mirror=https://reg-mirror.qiniu.com 选项说明: --vm-driver 如果不写会自动检测,可选值 virtualbox, vmwarefusion, hyperv, vmware --image-mirror-country 需要使用的镜像镜像的国家/地区代码。留空以使用全球代码。对于中国大陆用户,请将其设置为 cn。 --image-repository 用来拉取 Kubernetes 集群所需镜像的仓库 --iso-url 下载 minikube 虚机安装所需的 iso 文件 --registry-mirror docker registry 的镜像源,集群安装后拉取镜像加速用,可以使用其它加速器地址 更多选项可以执行 minikube start --help 首先是下载 iso 镜像: * minikube 1.8.2 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.8.2 * To disable this notice, run: 'minikube config set WantUpdateNotification false' ! Microsoft Windows 10 Pro 10.0.18362 Build 18362 上的 minikube v1.7.3 * Using the virtualbox driver based on user configuration * 正在使用镜像存储库 registry.cn-hangzhou.aliyuncs.com/google_containers * 正在下载 VM boot image... > minikube-v1.7.3.iso: 30.81 MiB / 167.39 MiB 18.41% 830.43 KiB p/s ETA 2m 这时候会自动创建 C:\Users\你的用户名\.minikube 文件夹,该目录下有一个 cache 文件夹,下载的文件都会缓存在这里。 接下来是创建虚机: * 正在创建 virtualbox 虚拟机(CPUs=2,Memory=2000MB, Disk=20000MB)... * 正在 Docker 19.03.6 中准备 Kubernetes v1.17.3… 这里的虚机配置对应的选项: --cpu=2, --memory='2000mb',--disk-size='20000mb',可以自己指定。 这个阶段虚机内部开始拉取镜像,所以会花一点时间,可以另起一个命令行,执行: > minikube ssh _ _ _ _ ( ) ( ) ___ ___ (_) ___ (_)| |/') _ _ | |_ __ /' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\ | ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/ (_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____) $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy v1.17.3 ae853e93800d 4 weeks ago 116MB registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver v1.17.3 90d27391b780 4 weeks ago 171MB registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager v1.17.3 b0f1517c1f4b 4 weeks ago 161MB registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler v1.17.3 d109c0821a2b 4 weeks ago 94.4MB registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard v2.0.0-beta8 eb51a3597525 3 months ago 90.8MB registry.cn-hangzhou.aliyuncs.com/google_containers/coredns 1.6.5 70f311871ae1 4 months ago 41.6MB registry.cn-hangzhou.aliyuncs.com/google_containers/etcd 3.4.3-0 303ce5db0e90 4 months ago 288MB registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper v1.0.2 3b08661dc379 4 months ago 40.1MB registry.cn-hangzhou.aliyuncs.com/google_containers/pause 3.1 da86e6ba6ca1 2 years ago 742kB registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner v1.8.1 4689081edb10 2 years ago 80.8MB $ 回到安装所在的命令行,可以看到需要下载的程序: 如果感觉半天没动静了,可以按一下回车 * 正在 Docker 19.03.6 中准备 Kubernetes v1.17.3… * 正在下载 kubelet v1.17.3 * 正在下载 kubectl v1.17.3 * 正在下载 kubeadm v1.17.3 下载后的文件仍然是保存在 C:\Users\你的用户名\.minikube\cache\linux\v1.17.3 文件夹中,如果这里下载的较慢,可以: 提前下载好对应的文件 此处按下 Ctrl-C 中断 minikube 把文件拷贝到对应的文件夹下 重新执行上面的 minikube start minikube 会从中断处继续往下执行。 * 正在启动 Kubernetes ... * Enabling addons: default-storageclass, storage-provisioner * 等待集群上线... * 完成!kubectl 已经配置至 "minikube" * 为获得最佳结果,请安装 kubectl:https://kubernetes.io/docs/tasks/tools/install-kubectl/ 安装完成,来看看集群的状态: > minikube kubectl get nodes * 正在下载 kubectl.exe v1.17.3 这里又要下载 Windows 系统下的 kubectl 客户端程序,下载后的文件保存在 C:\Users\你的用户名\.minikube\cache\windows\v1.17.3 文件夹中,如果这里下载的较慢,仍然可以提前下载好拷贝过去。 > minikube kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 11m v1.17.3 就绪状态,开始启动 dashboard: > minikube dashboard X kubectl not found in PATH, but is required for the dashboard. Installation guide: https://kubernetes.io/docs/tasks/tools/install-kubectl/ 这里提示我们没有在环境变量 PATH 中找到 kubectl,只需要将上面下载下来的 kubectl.exe 拷贝到任何一个已经在 PATH 中的目录即可。为了方便管理,我们可以把它和 minikube.exe 放一起。 > minikube dashboard * 正在开启 dashboard ... * Verifying dashboard health ... * Launching proxy ... * Verifying proxy health ... * Opening http://127.0.0.1:54032/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser... 此时命令行会一直阻塞在这里,自动打开浏览器,进入 Dashboard: 对于手动部署过 dashboard 的人来说,这个确实太方便了 并且后续可以直接使用 kubectl 命令来操作集群: > kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-7f9c544f75-kw6g9 1/1 Running 0 29m kube-system coredns-7f9c544f75-p84v8 1/1 Running 0 29m kube-system etcd-minikube 1/1 Running 0 29m kube-system kube-apiserver-minikube 1/1 Running 0 29m kube-system kube-controller-manager-minikube 1/1 Running 0 29m kube-system kube-proxy-4jf76 1/1 Running 0 29m kube-system kube-scheduler-minikube 1/1 Running 0 29m kube-system storage-provisioner 1/1 Running 1 29m kubernetes-dashboard dashboard-metrics-scraper-7b64584c5c-x7bwz 1/1 Running 0 14m kubernetes-dashboard kubernetes-dashboard-79d9cd965-lq7xj 1/1 Running 0 14m 直接 SSH 连接集群 在命令行执行 minikube ssh 可以进入到虚机内部,但是因为终端类型的原因,会出现乱码,比如执行 top 命令: 所以最好还是通过模拟终端工具(Xshell/SecureCRT等)登入, 先执行 minikube ip 查询到虚机的 IP 地址 SSH 用户名选择为 docker 认证方式选择为 Public Key, 选择对应的私钥文件,C:\Users\你的用户名\.minikube\machines\minikube\id_rsa 附:最新 minikube v1.8.2 安装说明 执行: minikube start --driver=virtualbox --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://reg-mirror.qiniu.com --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.8.0.iso --driver: 原 --vm-driver 改为 --driver --image-mirror-country: 带上该选项会报错,不带也没影响 --image-repository:一样 --iso-url 注意版本号 --registry-mirror: 同上 安装过程中不再需要下载那 3 个文件,改为下载 preloaded-images-k8s-v1-v1.17.3-docker-overlay2.tar.lz4 的镜像文件,大小 500MB,保存在 C:\Users\你的用户名\.minikube\cache\preloaded-tarball。 支持断点续传,并且可以提前把下载好的文件拷贝过去。 其它步骤和 v1.7.3 一样,不再赘述。 文章内容虽基础,整理发布不轻松 如果看过有帮助,不妨 点赞 + 关注,谢谢!

优秀的个人博客,低调大师

借助URLOS快速安装MixPHP-2.0.1框架

环境需求 最低硬件配置:1核CPU,1G内存(1+1)提示:如果你的应用较多,而主机节点的硬件配置较低,建议在部署节点时开通虚拟虚拟内存; 生产环境建议使用2G或以上内存; 推荐安装系统:Ubuntu-16.04、Ubuntu-18.04、CentOS7.X、Debian9X的64位的纯净的操作系统; URLOS安装 curl -LO www.urlos.com/iu && sh iu MixPHP安装流程 登录URLOS系统后台,在应用市场中搜索“MixPHP”,找到之后,直接点击安装按钮 填写服务名称、选择运行节点、服务端口、选择智能部署 填写网站域名、ssh密码(这里的密码是root密码) 然后点击“提交”按钮,等待部署完成; 访问网站访问:www.aaa.com:8088(这里是自己的域名) 登录sftp 网站根目录在 data/www/mix/

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册