首页
关于
留言
Search
1
红米 AX3000 (AX6) 路由器解锁 SSH 教程
6,676 阅读
2
网盘挂载程序sharelist美化教程
4,216 阅读
3
小米路由器 AX3600 开启SSH教程,官方固件即可安装 ShellClash开启科学上网
2,168 阅读
4
Oracle 甲骨文 ARM VPS 自动抢购脚本
1,819 阅读
5
编译带PassWall和SSR-plus插件的Openwrt系统
1,393 阅读
前端
Vue
React
后端
Java
Python
PHP
数据库
运维
杂谈
小程序
影视资源
登录
Search
标签搜索
Java
Linux
Mysql
IDEA
Debian
Docker
Springboot
CentOS
Cloudflare
Maven
JavaScript
SQL
Wordpress
宝塔
Nginx
Windows
MacBook
JS
CSS
Openwrt
William
累计撰写
144
篇文章
累计收到
702
条评论
首页
栏目
前端
Vue
React
后端
Java
Python
PHP
数据库
运维
杂谈
小程序
影视资源
页面
关于
留言
搜索到
144
篇与
的结果
2023-03-29
如何下载最新版和历史版Chrome离线安装包?
Chrome(谷歌浏览器)是目前世界上最为流行的浏览器。在国内,我们要如何为电脑安装最新版和历史版的 Chrome 呢?除了在线安装,有没有办法下载 Chrome 的离线安装包呢?虽然 Google 的大多数服务早已离我们远去,但在国内,我们还是能够直接从官网下载 Chrome 安装包的。打开下方网址,点击网页中的 下载 Chrome 选项,它会自动检测并提供符合你的设备系统的安装包。下载地址:https://www.google.com/chrome/2、离线版 Chrome想要下载 Chrome指定版本的离线安装包,也非常简单,只需要在下载地址后添加一些参数。以下载 Window 64位稳定版为例,在地址栏打开以下网址即可下载:下载地址:https://www.google.com/chrome/?standalone=1&platform=win64&extra=stablechannelstandalone= 1 指离线安装包;platform= win64 指 window 64位;win 指 window 32位;mac 指 Mac版;extra= stablechannel指稳定版;betachannel 指测试版;devchannel 指开发版;canarychannel 指金丝雀版。3、历史版 Chrome该网址提供的文件下载地址,是 Chrome 官方的。下载地址:https://vikyd.github.io/download-chromium-history-version/
2023年03月29日
165 阅读
0 评论
0 点赞
2022-10-30
什么叫做Redis - 一个深入的教程
Redis("REmote DIctionary Service")是一个开源的键值数据库服务器。对Redis最准确的描述是,它是一个数据结构服务器。Redis的这一特定性质导致了它在开发者中的大部分流行和采用。与其迭代、分类和排序行,如果数据是你从头开始想要的数据结构,会怎么样呢?早期,它的使用方式很像Memcached,但随着Redis的改进,它在许多其他用例中变得可行,包括发布-订阅机制、流和队列。主要而言,Redis是一个内存数据库,在另一个 "真正的 "数据库(如MySQL或PostgreSQL)前面用作缓存,以帮助提高应用程序的性能。它利用了内存的速度,减轻了中央应用数据库的负载。不经常变化和经常被请求的数据对任务要求不高但经常演变的数据。上述数据的例子可以包括会话或数据缓存和排行榜或仪表盘的滚动分析。然而,对于许多用例,Redis提供了足够的保证,它可以作为一个成熟的主数据库使用。再加上Redis插件和它的各种高可用性(HA)设置,Redis作为一个数据库对于某些场景和工作负载来说已经变得非常有用。另一个重要方面是,Redis模糊了缓存和数据存储之间的界限。这里需要理解的重要一点是,在内存中读取和操作数据的速度比使用SSD或HDD的传统数据存储的速度要快得多。最初,Redis最常被拿来与Memcached比较,后者在当时缺乏任何非易失性的持久性。Memcached是由Brad Fitzpatrick在2003年创建的,比Redis早了6年。它最初是一个Perl项目,后来用C语言重写。它是当时事实上的缓存工具。它和Redis的主要区别在于它缺乏数据类型,而且它的驱逐策略有限,只有LRU(最近使用最少的)。另一个区别是,Redis是单线程的,而Memcached是多线程的。Memcached在严格的缓存环境中可能表现良好,但在分布式集群中需要一些设置,而Redis天生就支持。以下是目前这两个缓存之间的能力细分。 内存缓存雷迪斯亚毫秒延迟是的是的开发者易用性是的是的数据分区是的是的支持广泛的编程语言是的是的高级数据结构-是的多线程架构是的-快照-是的复制-是的交易-是的发布/订阅-是的Lua 脚本-是的地理空间支持-是的虽然现在可以配置它将数据持久化到磁盘的方式,但在刚推出时,Redis使用快照,将内存中的数据的异步拷贝持久化到磁盘上进行长期存储。不幸的是,这种机制有一个缺点,就是在快照之间可能会丢失你的数据。自2009年成立以来,Redis已经发展成熟。我们将介绍它的大部分架构和拓扑结构,这样你就可以把Redis加入你的数据存储系统库中。Redis 架构在我们开始讨论Redis的内部结构之前,让我们讨论一下各种Redis的部署和它们的取舍。我们将主要关注这些配置。单个 Redis 实例Redis 高可用性Redis 哨兵Redis 集群根据您的用例和规模,您可以决定使用一种设置或另一种设置。单个 Redis 实例单个 Redis 实例是最直接的 Redis 部署。它允许用户设置和运行可以帮助他们发展和加速服务的小型实例。但是,这种部署并非没有缺点。例如,如果此实例失败或不可用,则所有客户端对 Redis 的调用都会失败,从而降低系统的整体性能和速度。如果有足够的内存和服务器资源,这个实例可以很强大。主要用于缓存的场景可能会以最少的设置显着提升性能。给定足够的系统资源,您可以在应用程序运行的同一机器上部署此 Redis 服务。了解一些有关管理系统内数据的 Redis 概念是必不可少的。发送到 Redis 的命令首先在内存中处理。然后,如果在这些实例上设置了持久性,则在某个时间间隔上会有一个fork进程,以促进数据持久性 RDB(Redis 数据的非常紧凑的时间点表示)快照或 AOF(仅附加文件)。这两个流程让 Redis 拥有长期存储,支持各种复制策略,并启用更复杂的拓扑。如果 Redis 未设置为保留数据,则在重新启动或故障转移时数据会丢失。如果在重启时启用了持久性,它会将 RDB 快照或 AOF 中的所有数据加载回内存中,然后实例可以支持新的客户端请求。话虽如此,让我们看看您可能想要使用的更多分布式 Redis 设置。Redis 高可用性Redis 的另一个流行设置是主部署和与复制保持同步的辅助部署。当数据写入主实例时,它会将这些命令的副本发送到辅助实例的副本客户端输出缓冲区,这有助于复制。辅助实例可以是部署中的一个或多个实例。这些实例可以帮助扩展从 Redis 的读取或提供故障转移,以防 main 丢失。高可用性高可用性(HA)是一个系统的特点,旨在确保在高于平均水平的时间内,达到约定的运行性能水平,通常是正常运行时间。在这些HA系统中,不出现单点故障是至关重要的,这样系统就可以优雅而快速地恢复。这导致了可靠的交叉,所以数据在从主站到副站的过渡期间不会丢失,此外,还可以自动检测故障并从中恢复。由于我们现在已经进入了一个分布式系统,因此您需要在此拓扑中考虑许多新事物。以前简单的事情现在变得更加复杂。Redis 复制Redis 的每个主实例都有一个复制 ID 和一个偏移量。这两条数据对于确定副本可以继续其复制过程的时间点或确定它是否需要进行完整同步至关重要。对于主 Redis 部署上发生的每个操作,此偏移量都会增加。Replication ID, offset更明确地说,当 Redis 副本实例仅落后于主实例几个偏移量时,它会从主实例接收剩余的命令,然后在其数据集上重播,直到同步。如果两个实例无法就复制 ID 达成一致,或者主实例不知道偏移量,则副本将请求完全同步。这涉及到一个主实例创建一个新的 RDB 快照并将其发送到副本。在发生此传输时,主实例正在缓冲快照截止和当前偏移之间的所有中间更新,以便在与快照同步后发送到辅助实例。完成后,复制可以正常继续。如果一个实例具有相同的复制 ID 和偏移量,则它们具有完全相同的数据。现在您可能想知道为什么需要复制 ID。当 Redis 实例被提升为主实例或作为主实例从头开始重新启动时,它会被赋予一个新的复制 ID。这用于推断此新提升的辅助实例从中复制的先前主实例。这允许执行部分同步(与其他辅助节点),因为新的主实例会记住其旧的复制 ID。例如,两个实例(主实例和辅助实例)具有相同的复制 ID,但偏移量相差几百个命令,这意味着如果在偏移量后面的实例上重放这些实例,它们将具有相同的数据集。现在,如果复制 ID 完全不同,并且我们不知道新降级(并重新加入)辅助节点的先前复制 ID(没有共同祖先)。我们将需要执行昂贵的完全同步。或者,如果我们知道以前的复制 ID,我们就可以推断如何使数据同步,因为我们能够推断出它们共享的共同祖先,并且偏移量对于部分同步再次有意义。Redis 哨兵Sentinel 是一个分布式系统。与所有分布式系统一样,Sentinel 有几个优点和缺点。Sentinel 的设计方式是,一组哨兵进程协同工作以协调状态,从而为 Redis 提供高可用性。毕竟,您不希望保护您免受故障影响的系统有自己的单点故障。Sentinel 负责一些事情。首先,它确保当前的主实例和辅助实例正常运行并做出响应。这是必要的,因为哨兵(与其他哨兵进程)可以在主节点和/或辅助节点丢失的情况下发出警报并采取行动。其次,它在服务发现中发挥作用,就像其他系统中的 Zookeeper 和 Consul 一样。所以当一个新的客户端尝试向 Redis 写东西时,Sentinel 会告诉客户端当前的主实例是什么。因此,哨兵不断监控可用性并将该信息发送给客户端,以便他们能够在他们确实进行故障转移时对其做出反应。以下是它的职责:监控——确保主要和次要实例按预期工作。通知—通知系统管理员 Redis 实例中的事件。故障转移管理——如果主实例不可用并且足够多的(法定人数)节点同意这是真的,Sentinel 节点可以启动故障转移过程。配置管理——Sentinel 节点还充当当前主要 Redis 实例的发现点。以这种方式使用 Redis Sentinel 可以进行故障检测。此检测涉及多个哨兵进程同意当前主实例不再可用。这个协议过程称为 Quorum。这可以提高鲁棒性并防止一台机器行为异常并且无法访问主 Redis 节点。法定人数法定人数是指一个分布式系统为了被允许执行故障转移等操作而必须获得的最低票数。这个数字是可配置的,但应该反映出该分布式系统中的节点数量。大多数分布式系统的规模为3个或5个,四分位数分别为2个和3个。在系统需要打破平局的情况下,奇数的节点是比较好的。此设置并非没有缺点,因此我们将在使用 Redis Sentinel 时介绍一些建议和最佳实践。您可以通过多种方式部署 Redis Sentinel。老实说,要提出任何明智的建议,我需要比目前有关您的系统的更多背景信息。作为一般指导,我建议在每个应用程序服务器旁边运行一个哨兵节点(如果可能),这样你也不需要考虑哨兵节点和实际使用 Redis 的客户端之间的网络可达性差异。您可以将 Sentinel 与 Redis 实例一起运行,甚至可以在独立节点上运行,但这会以不同的方式使事情复杂化。我建议至少运行三个具有至少两个法定人数的节点。这是一个简单的图表,分解了集群中的服务器数量以及相关的法定人数和可容忍的可持续故障。服务器数量法定人数允许的故障数110220321431532642743服务器数量和允许故障数量的仲裁表。这会因系统而异,但总体思路是不变的。让我们花点时间思考一下这样的设置会出现什么问题。如果你运行这个系统足够长的时间,你会遇到所有这些。如果哨兵节点超出法定人数怎么办?如果网络分裂将旧的主实例置于少数群体中怎么办?这些写入会发生什么?(剧透:当系统完全恢复时它们会丢失)如果哨兵节点和客户端节点(应用程序节点)的网络拓扑错位会发生什么?没有持久性保证,特别是因为磁盘的持久性(见下文)是异步的。还有一个烦人的问题,当客户发现新的primary时,我们失去了多少写给一个不知道的primary?Redis 建议在建立新连接时查询新的主节点。根据系统配置,这可能意味着大量数据丢失。如果您强制主实例将写入复制到至少一个辅助实例,有几种方法可以减轻损失程度。请记住,所有 Redis 复制都是异步的,并且有其权衡。因此,它需要独立跟踪确认,如果它们没有得到至少一个辅助实例的确认,主实例将停止接受写入。Redis 集群我相信很多人都想过当您无法将所有数据存储在一台机器上的内存中时会发生什么。目前,单个服务器中可用的最大 RAM 为 24TIB,目前在 AWS 上在线列出。当然,这很多,但对于某些系统来说,这还不够,即使对于缓存层也是如此。Redis Cluster 允许 Redis 的水平扩展。垂直和水平缩放随着系统的发展,您有三个选择。少做(没有人会完全这样做,因为我们是贪得无厌的怪物)。放大。向外扩展。认真对待后两者,放大和缩小分别称为垂直和水平缩放。垂直扩展是一种技术,您可以让更大更好的机器更快地完成工作,并希望您的所有问题都能与您的硬件一起很好地扩展。即使这是可能的,您最终也会受到您使用的硬件的限制。一旦达到这一点(更有可能并且希望早于这一点),您将需要通过将工作负载分散到负责整体较小部分的多台较小机器上来水平扩展系统。因此,让我们先弄清楚一些术语;一旦我们决定使用Redis集群,我们就决定将我们要存储的数据分散到多台机器上,称为分片。因此,集群中的每个Redis实例被认为是整个数据的一个分片。这就带来了一个新的问题。如果我们向集群推送一个密钥,我们如何知道哪个Redis实例(分片)在保存该数据?有几种方法可以做到这一点,但Redis Cluster使用算法分片。为了找到一个给定密钥的分片,我们对密钥进行散列,并将总结果与分片的数量相乘。然后,使用一个确定的哈希函数,这意味着一个给定的密钥将总是映射到同一个分片,我们可以推理出一个特定的密钥在未来读取它时将在哪里。当我们后来想在系统中添加一个新的分片时会发生什么?这个过程被称为重新分片。假设钥匙 "foo "在引入一个新的分片后被映射到零号分片,它可能被映射到五号分片。然而,如果我们需要快速增长系统,移动数据以反映新的分片映射将是缓慢和不现实的。这对Redis集群的可用性也有不利影响。Redis Cluster为这个问题设计了一个叫做Hashslot的解决方案,所有的数据都被映射到这个Hashslot中。有16K个hashslot。这为我们提供了一个合理的方法,将数据分散到整个集群中,当我们添加新的分片时,我们只需在系统中移动哈希槽。通过这样做,我们只需要将哈希槽从分片区移动到分片区,并简化了向集群中添加新的主实例的过程。这是在没有任何停机时间的情况下实现的,对性能的影响也很小。让我们通过一个例子来谈谈。M1包含从0到8191的哈希槽。M2包含从8192到16383的哈希槽。因此,为了映射 "foo",我们对密钥(foo)进行确定性的哈希运算,然后用哈希槽的数量(16K)进行修改,从而得到M2的映射。现在我们假设增加一个新的实例,M3。新的映射将是M1包含从0到5460的哈希槽。M2包含从5461到10922的哈希槽。M3包含从10923到16383的哈希槽。所有映射M1中的哈希槽的键现在都映射到了M2中,这些键都需要移动。但是单个键对哈希槽的散列就不需要移动了,因为它们已经在哈希槽中被划分了。因此,这一级的误导解决了算法分片的重新分片问题。GossipingRedis Cluster使用gossip协议来确定整个集群的健康状况。在上面的插图中,我们有3个M节点和3个S节点。所有这些节点不断进行通信,以了解哪些分片是可用的,并准备为请求提供服务。如果有足够多的分片同意M1没有响应,它们可以决定将M1的二级S1提升为一级,以保持集群的健康。触发这一点所需的节点数量是可配置的,而且必须正确对待这个问题。如果你做得不恰当,你可能会出现这样的情况:当分区的两边都相等时,如果不能打破平局,集群就会分裂。这种现象被称为分裂的大脑。作为一般规则,必须要有奇数的主节点和每个节点的两个副本,这样的设置才是最稳健的。Redis 持久化模型如果我们要使用Redis来存储任何种类的数据进行安全保管,那么了解Redis是如何做到的就很重要了。在很多情况下,如果你丢失了Redis所存储的数据,并不是世界末日。把它作为一个缓存,或者在它为实时分析提供动力的情况下,如果数据丢失,也不是世界末日。在其他情况下,我们希望对数据的持久性和恢复有一些保证。无持久性无持久性:如果你愿意,你可以完全禁用持久性。这是运行Redis的最快方式,没有持久性保证。RDBRDB (Redis数据库)。RDB持久化在指定的时间间隔内对你的数据集进行时间点快照。这种机制的主要缺点是,快照之间的数据会丢失。此外,这种存储机制还依赖于fork主进程,在一个较大的数据集中,这可能导致服务请求的瞬间延迟。也就是说,RDB文件在内存中的加载速度比AOF快得多。AOFAOF(仅附加文件):AOF持久性记录了服务器收到的每一个写操作,这些操作将在服务器启动时再次播放,重建原始数据集。这种确保持久性的方式比RDB快照更持久,因为它是一个只需追加的文件。当操作发生时,我们把它们缓冲到日志中,但它们还没有被持久化。这个日志包含了我们实际运行的命令,以便在需要时进行重放。然后在可能的情况下,我们用fsync把它冲到磁盘上(何时运行是可配置的),它将被持久化。缺点是格式不紧凑,比RDB文件占用更多磁盘。fsync()将文件描述符fd所指的文件的所有修改的核心数据(即修改的缓冲缓存页)转移("冲刷")到磁盘设备(或其他永久存储设备),这样即使系统崩溃或重启,也可以检索到所有改变的信息。由于各种原因,当对文件进行修改时,它们是在缓存中进行的,对fsync()的调用确保它们被持久化到磁盘上,以后可以访问。能不能两个都用?RDB + AOF:可以将 AOF 和 RDB 组合在同一个 Redis 实例中。如果以某种速度换取耐用性是一种折衷,那么您愿意做到。我认为这是设置 Redis 的一种可接受的方式。在重启的情况下,请记住如果两者都启用,Redis 将使用 AOF 来重建数据,因为它是最完整的。Fork同步现在我们了解了持久化的类型,让我们来讨论一下在像Redis这样的单线程应用程序中,我们究竟如何去做。在我看来,Redis最酷的部分是它如何利用fork和写时拷贝来促进数据的持久性。Fork是操作系统通过创建自己的副本来创建新进程的一种方式。通过这种方式,你可以得到一个新的进程ID和其他一些信息和句柄,所以新fork的进程(子进程)可以与原始进程的父进程对话。现在是事情变得有趣的地方。Redis是一个分配有大量内存的进程,那么它如何在不耗尽内存的情况下进行复制呢?当你fork一个进程时,父进程和子进程共享内存,在该子进程中Redis开始快照(Redis)进程。这是由一种称为 "写时复制 "的内存共享技术实现的--该技术传递对fork创建时的内存的引用。如果在子进程持久化到磁盘时没有发生变化,就不会进行新的分配。在有变化的情况下,内核会跟踪每个页面的引用,如果对特定页面有多个引用,那么这些变化会被写入新的页面。子进程完全不知道这些变化,并且有一致的内存快照。因此,只有一小部分内存被使用,我们能够非常快速和有效地实现潜在的数千兆字节内存的时间点快照!
2022年10月30日
32 阅读
0 评论
0 点赞
2022-10-29
如何利用Maven将代码打包成第三方公共jar包?
一、摘要在项目开发过程中,我们经常需要将一些公共方法提取出来,然后单独封装成一个第三方公共jar包,采用普通的方式打包后的jar,依赖的工程执行编译时,却提示找不到对应的依赖包,那么如何将工程打包为可执行jar包呢?下面向大家介绍三种通过maven将工程打包成可执行的打包方式。二、方法实践2.1、assembly插件2.1.1、pom.xml的相关配置文件如下<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.java</groupId> <artifactId>example-frame-fatJar</artifactId> <version>1.0.0</version> ..... <build> <finalName>sso-api</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- maven-assembly-plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.6</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <encoding>UTF-8</encoding> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>2.1.2、运行如下命令,进行打包mvn clean package会在target文件夹里生成一个jar-with-dependencies的jar是可执行的。2.1.3、验证jar是否可执行在带有 jar-with-dependencies 的jar文件下,打开终端,输入如下命令#验证jar是否可执行,如果没有报错,说明没有问题 java -jar xxx-jar-with-dependencies.jar2.2、shade插件2.2.1、pom.xml的相关配置文件如下<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.java</groupId> <artifactId>example-frame-fatJar</artifactId> <version>1.0.0</version> ...... <build> <finalName>sso-api</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- maven-shade-plugin,不同的是shade可以将多个相同的配置文件追加合并 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.xxg.Main</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>2.2.2、运行如下命令,进行打包mvn clean package发现生成了2个jar包,一个为:original-XXX.jar,另一个为:XXX.jar,其中original...jar里只包含了工程自己的class文件,而另外的一个jar包则包含了工程本身以及所有依赖的jar包的class文件。我们只需要使用第二个jar包就可以了。2.2.3、验证jar是否可执行在XXX.jar文件下,打开终端,输入如下命令#验证jar是否可执行,如果没有报错,说明没有问题 java -jar XXX.jar不同点:shade可以将多个相同的配置文件追加合并,比如,多个子项目下有相同的配置文件,shade在打包的时候,会将相同的配置文件合并。2.3、Fatjar打包工具(eclipse插件)2.3.1、eclipse在线安装插件1、打开eclipse,打开菜单help > Install New Sofware > Add...name:FatJarURL:http://kurucz-grafika.de/fatjar根据提示下载安装并重启 eclipse!2.3.2、FatJar 使用在使用Eclipse进行导出时,点击项目右键,在弹出的右键菜单中选择 Build Fat Jar, 打开配置Fat Jar弹出框;或者,项目右键,点击Export,然后在打开的Export选择框中选择 Other 下面的 Fat Jar Exporter, 选择需要导出的项目,点击下一步打开配置Fat Jar弹出框。2.3.3、验证jar是否可执行在 XXX.jar 文件下,打开终端,输入如下命令#验证jar是否可执行,如果没有报错,说明没有问题 java -jar XXX.jar
2022年10月29日
11 阅读
0 评论
0 点赞
2022-10-22
如何编写一套多线程的测试用例?
一、摘要很多时候,新开发的功能在上线之前,我们都会进行压力测试,以防上线之后,突然出现性能瓶颈或者出现线程安全问题。那么问题来了,如何进行压力测试呢?实践的手段有很多种,比如采用 jmeter 、fiddler、postman 等第三方工具,可以快速实现性能压力测试。当然除此之外,其实我们也利用 java 的多线程特性,完全可以自行编写一套多线程的压力测试。下面我们以 访问百度首页服务 为例,向大家演示一下,采用 java 的多线程特性,该如何编写并发测试。二、代码实践方案一说到多线程,大家可能想到的就是实例化一个Thread对象,然后启动它,就可以实现异步处理,以模拟100个用户同时请求百度首页为例,代码实践如下:public static void main(String[] args) throws InterruptedException { //模拟100个线程,同时请求百度首页 long start = System.currentTimeMillis(); final int threadNum = 100; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; new Thread(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); //访问百度首页 String url = "https://www.baidu.com"; String rs = HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + rs); System.out.println("thread " + threadCount + " final"); //执行完成之后,计数器减一 countDownLatch.countDown(); } }).start(); } //线程同步阻塞 countDownLatch.await(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms"); }实践过程非常简单,采用Thread + CountDownLatch组合,进行阻塞测试。但是实际上往往我们进行多线程模拟用户进行访问某个服务的时候,每个用户的请求参数是不一样的,这个时候我们应该如何更加真实的贴近用户实际请求去测试呢?请看下面这个方案!方案二实际上在多线程并发编程中,它还有一个完美搭档,那就是 队列,采用 多线程+队列 组合编程模型,可以实现带任务的异步处理,并且性能高效!下面我们还是以 访问百度首页服务 为例,采用 多线程+队列 组合模式来模拟 100 个用户总共发起了1000次访问百度首页,代码实践如下!public static void main(String[] args) throws InterruptedException { //将每个用户访问百度服务的请求参数,存入阻塞队列BlockingQueue中 BlockingQueue<String> queue = new LinkedBlockingQueue<>(); for (int i = 0; i < 1000; i++) { queue.put("https://www.baidu.com?paramKey=" + i); } //模拟100个线程,执行1000次请求访问百度 long start = System.currentTimeMillis(); final int threadNum = 100; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; new Thread(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); boolean over = false; while (!over) { String url = queue.poll(); if(Objects.nonNull(url)) { //发起请求 String result =HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + result); }else { //任务结束 over = true; System.out.println("thread " + threadCount + " final"); countDownLatch.countDown(); } } } }).start(); } countDownLatch.await(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms"); }当然,你还可以自由调整线程数,也可以采用 juc 包的线程池来实现多线程编程,改造逻辑如下:public static void main(String[] args) throws InterruptedException { //将每个用户访问百度服务的请求参数,存入阻塞队列BlockingQueue中 BlockingQueue<String> queue = new LinkedBlockingQueue<>(); for (int i = 0; i < 1000; i++) { queue.put("https://www.baidu.com?paramKey=" + i); } //模拟100个线程,执行1000次请求访问百度 long start = System.currentTimeMillis(); final int threadNum = 100; //线程计数器 final CountDownLatch countDownLatch = new CountDownLatch(threadNum); //执行线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadNum); for (int i = 0; i < threadNum; i++) { final int threadCount = i + 1; fixedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println("thread " + threadCount + " start"); boolean over = false; while (!over) { String url = queue.poll(); if(Objects.nonNull(url)) { //发起请求 String result =HttpUtils.getUrl(url); System.out.println("thread " + threadCount + " run result:" + result); }else { //任务结束 over = true; System.out.println("thread " + threadCount + " final"); countDownLatch.countDown(); } } } }); } countDownLatch.await(); fixedThreadPool.shutdown(); System.out.println("执行耗时:" + (System.currentTimeMillis() - start) + "ms"); }其中 BlockingQueue 阻塞队列,支持线程数据共享,当一个线程把数据取出之后,另一个线程无法再取,最后的运行效果是一样的!
2022年10月22日
27 阅读
0 评论
0 点赞
2022-08-20
此内容被密码保护
加密文章,请前往内页查看详情
2022年08月20日
41 阅读
0 评论
0 点赞
2022-07-30
OpenWRT 软件包中文对照说明
选择LuCI 配置 添加插件应用:常用LuCI ---> Applications ---> luci-app-accesscontrol #访问时间控制 LuCI ---> Applications ---> luci-app-adbyby-plus #广告屏蔽大师Plus + LuCI ---> Applications ---> luci-app-arpbind #IP/MAC绑定 LuCI ---> Applications ---> luci-app-autoreboot #支持计划重启 LuCI ---> Applications ---> luci-app-ddns #动态域名 DNS(集成阿里DDNS客户端) LuCI ---> Applications ---> luci-app-filetransfer #文件传输(可web安装ipk包) LuCI ---> Applications ---> luci-app-firewall #添加防火墙 LuCI ---> Applications ---> luci-app-flowoffload #Turbo ACC网络加速(集成FLOW,BBR,NAT,DNS... LuCI ---> Applications ---> luci-app-frpc #内网穿透 Frp LuCI ---> Applications ---> luci-app-guest-wifi #WiFi访客网络 LuCI ---> Applications ---> luci-app-mwan3 #MWAN3负载均衡 LuCI ---> Applications ---> luci-app-mwan3helper #MWAN3分流助手 LuCI ---> Applications ---> luci-app-nlbwmon #网络带宽监视器 LuCI ---> Applications ---> luci-app-ramfree #释放内存 LuCI ---> Applications ---> luci-app-samba #网络共享(Samba) LuCI ---> Applications ---> luci-app-sqm #流量智能队列管理(QOS) LuCI ---> Applications ---> luci-app-syncdial #多拨虚拟网卡(原macvlan) LuCI ---> Applications ---> luci-app-unblockmusic #解锁网易云灰色歌曲 LuCI ---> Applications ---> luci-app-upnp #通用即插即用UPnP(端口自动转发) LuCI ---> Applications ---> luci-app-vlmcsd #KMS服务器设置 LuCI ---> Applications ---> luci-app-vsftpd #FTP服务器 LuCI ---> Applications ---> luci-app-wifischedule #WiFi 计划 LuCI ---> Applications ---> luci-app-wol #WOL网络唤醒 LuCI ---> Applications ---> luci-app-wrtbwmon #实时流量监测 LuCI ---> Applications ---> luci-app-xlnetacc #迅雷快鸟 LuCI ---> Applications ---> luci-app-zerotier #ZeroTier内网穿透 Extra packages ---> ipv6helper #支持 ipv6以下是全部:注:应用后面标记 “ * ” 为最近新添加LuCI ---> Applications ---> luci-app-accesscontrol #访问时间控制 LuCI ---> Applications ---> luci-app-acme #ACME 自动化证书管理环境 LuCI ---> Applications ---> luci-app-adblock #ADB广告过滤 LuCI ---> Applications ---> luci-app-adbyby-plus #广告屏蔽大师Plus + LuCI ---> Applications ---> luci-app-adbyby #广告过滤大师(已弃) LuCI ---> Applications ---> luci-app-adkill #广告过滤(已弃) LuCI ---> Applications ---> luci-app-advanced-reboot #Linksys高级重启 LuCI ---> Applications ---> luci-app-ahcp #支持AHCPd LuCI ---> Applications ---> luci-app-aliddns #阿里DDNS客户端(已弃,集成至ddns) LuCI ---> Applications ---> luci-app-amule #aMule下载工具 LuCI ---> Applications ---> luci-app-aria2 # Aria2下载工具 LuCI ---> Applications ---> luci-app-arpbind #IP/MAC绑定 LuCI ---> Applications ---> luci-app-asterisk #支持Asterisk电话服务器 LuCI ---> Applications ---> luci-app-attendedsysupgrade #固件更新升级相关 LuCI ---> Applications ---> luci-app-autoreboot #支持计划重启 LuCI ---> Applications ---> luci-app-baidupcs-web #百度网盘管理 * LuCI ---> Applications ---> luci-app-bcp38 #BCP38网络入口过滤(不确定) LuCI ---> Applications ---> luci-app-bird1-ipv4 #对Bird1-ipv4的支持 LuCI ---> Applications ---> luci-app-bird1-ipv6 #对Bird1-ipv6的支持 LuCI ---> Applications ---> luci-app-bird4 #Bird 4(未知)(已弃) LuCI ---> Applications ---> luci-app-bird6 #Bird 6(未知)(已弃) LuCI ---> Applications ---> luci-app-bmx6 #BMX6路由协议 LuCI ---> Applications ---> luci-app-bmx7 #BMX7路由协议 LuCI ---> Applications ---> luci-app-caldav #联系人(已弃) LuCI ---> Applications ---> luci-app-cifsd #网络共享CIFS/SMB服务器 * LuCI ---> Applications ---> luci-app-cjdns #加密IPV6网络相关 LuCI ---> Applications ---> luci-app-clamav #ClamAV杀毒软件 LuCI ---> Applications ---> luci-app-commands #Shell命令模块 LuCI ---> Applications ---> luci-app-cshark #CloudShark捕获工具 LuCI ---> Applications ---> luci-app-ddns #动态域名 DNS(集成阿里DDNS客户端) LuCI ---> Applications ---> luci-app-diag-core #core诊断工具 LuCI ---> Applications ---> luci-app-dnscrypt-proxy #DNSCrypt解决DNS污染 LuCI ---> Applications ---> luci-app-dnsforwarder #DNSForwarder防DNS污染 LuCI ---> Applications ---> luci-app-dnspod #DNSPod动态域名解析 LuCI ---> Applications ---> luci-app-dockerman #Docker容器 * LuCI ---> Applications ---> luci-app-dump1090 #民航无线频率(不确定) LuCI ---> Applications ---> luci-app-dynapoint #DynaPoint(未知) LuCI ---> Applications ---> luci-app-e2guardian #Web内容过滤器 LuCI ---> Applications ---> luci-app-familycloud #家庭云盘 LuCI ---> Applications ---> luci-app-filetransfer #文件传输(可web安装ipk包) LuCI ---> Applications ---> luci-app-firewall #添加防火墙 LuCI ---> Applications ---> luci-app-flowoffload #Turbo ACC网络加速(集成FLOW,BBR,NAT,DNS... LuCI ---> Applications ---> luci-app-freifunk-diagnostics #freifunk组件 诊断(未知) LuCI ---> Applications ---> luci-app-freifunk-policyrouting #freifunk组件 策略路由(未知) LuCI ---> Applications ---> luci-app-freifunk-widgets #freifunk组件 索引(未知) LuCI ---> Applications ---> luci-app-frpc #内网穿透 Frp LuCI ---> Applications ---> luci-app-fwknopd #Firewall Knock Operator服务器 LuCI ---> Applications ---> luci-app-guest-wifi #WiFi访客网络 LuCI ---> Applications ---> luci-app-haproxy-tcp #HAProxy负载均衡-TCP LuCI ---> Applications ---> luci-app-hd-idle #硬盘休眠 LuCI ---> Applications ---> luci-app-hnet #Homenet Status家庭网络控制协议 LuCI ---> Applications ---> luci-app-ipsec-virtuald #virtual服务器 IPSec LuCI ---> Applications ---> luci-app-kodexplorer #KOD可道云私人网盘 LuCI ---> Applications ---> luci-app-kooldns #virtual**服务器 ddns替代方案(已弃) LuCI ---> Applications ---> luci-app-koolproxy #KP去广告(已弃) LuCI ---> Applications ---> luci-app-lxc #LXC容器管理 LuCI ---> Applications ---> luci-app-meshwizard #网络设置向导 LuCI ---> Applications ---> luci-app-minidlna #完全兼容DLNA / UPnP-AV客户端的服务器软件 LuCI ---> Applications ---> luci-app-mjpg-streamer #兼容Linux-UVC的摄像头程序 LuCI ---> Applications ---> luci-app-mtwifi #MTWiFi驱动的支持 * LuCI ---> Applications ---> luci-app-mmc-over-gpio #添加SD卡操作界面(已弃) LuCI ---> Applications ---> luci-app-multiwan #多拨虚拟网卡(已弃,移至syncdial) LuCI ---> Applications ---> luci-app-mwan #MWAN负载均衡(已弃) LuCI ---> Applications ---> luci-app-mwan3 #MWAN3负载均衡 LuCI ---> Applications ---> luci-app-mwan3helper #MWAN3分流助手 LuCI ---> Applications ---> luci-app-n2n_v2 #N2N内网穿透 N2N v2 virtual**服务 LuCI ---> Applications ---> luci-app-netdata #Netdata实时监控(图表) * LuCI ---> Applications ---> luci-app-nft-qos #QOS流控 Nftables版 LuCI ---> Applications ---> luci-app-ngrokc #Ngrok 内网穿透(已弃) LuCI ---> Applications ---> luci-app-nlbwmon #网络带宽监视器 LuCI ---> Applications ---> luci-app-noddos #NodDOS Clients 阻止DDoS攻击 LuCI ---> Applications ---> luci-app-nps #内网穿透nps * LuCI ---> Applications ---> luci-app-ntpc #NTP时间同步服务器 LuCI ---> Applications ---> luci-app-olsr #OLSR配置和状态模块 LuCI ---> Applications ---> luci-app-olsr-services #OLSR服务器 LuCI ---> Applications ---> luci-app-olsr-viz #OLSR可视化 LuCI ---> Applications ---> luci-app-oscam #OSCAM服务器(已弃) LuCI ---> Applications ---> luci-app-p910nd #打印服务器模块 LuCI ---> Applications ---> luci-app-pagekitec #Pagekite内网穿透客户端 LuCI ---> Applications ---> luci-app-polipo #Polipo代理(是一个小型且快速的网页缓存代理) LuCI ---> Applications ---> luci-app-pppoe-relay #PPPoE NAT穿透 点对点协议(PPP) LuCI ---> Applications ---> luci-app-privoxy #Privoxy网络代理(带过滤无缓存) LuCI ---> Applications ---> luci-app-qbittorrent #BT下载工具(qBittorrent) LuCI ---> Applications ---> luci-app-qos #流量服务质量(QoS)流控 LuCI ---> Applications ---> luci-app-radicale #CalDAV/CardDAV同步工具 LuCI ---> Applications ---> luci-app-ramfree #释放内存 LuCI ---> Applications ---> luci-app-rp-pppoe-server #Roaring Penguin PPPoE Server 服务器 LuCI ---> Applications ---> luci-app-samba #网络共享(Samba) LuCI ---> Applications ---> luci-app-samba4 #网络共享(Samba4) LuCI ---> Applications ---> luci-app-sfe #Turbo ACC网络加速(flowoffload二选一) LuCI ---> Applications ---> luci-app-shairplay #支持AirPlay功能 LuCI ---> Applications ---> luci-app-siitwizard #SIIT配置向导 SIIT-Wizzard LuCI ---> Applications ---> luci-app-simple-adblock #简单的广告拦截 LuCI ---> Applications ---> luci-app-smartdns #SmartDNS本地服务器 * LuCI ---> Applications ---> luci-app-splash #Client-Splash是无线MESH网络的一个热点认证系统 LuCI ---> Applications ---> luci-app-sqm #流量智能队列管理(QOS) LuCI ---> Applications ---> luci-app-squid #Squid代理服务器 LuCI ---> Applications ---> luci-app-statistics #流量监控工具 LuCI ---> Applications ---> luci-app-syncdial #多拨虚拟网卡(原macvlan) LuCI ---> Applications ---> luci-app-tinyproxy #Tinyproxy是 HTTP(S)代理服务器 LuCI ---> Applications ---> luci-app-transmission #BT下载工具 LuCI ---> Applications ---> luci-app-travelmate #旅行路由器 LuCI ---> Applications ---> luci-app-ttyd #网页终端命令行 LuCI ---> Applications ---> luci-app-udpxy #udpxy做组播服务器 LuCI ---> Applications ---> luci-app-uhttpd #uHTTPd Web服务器 LuCI ---> Applications ---> luci-app-unblockmusic #解锁网易云灰色歌曲 LuCI ---> Applications ---> luci-app-unblockneteasemusic-go #解锁网易云歌曲 * LuCI ---> Applications ---> luci-app-unbound #Unbound DNS解析器 LuCI ---> Applications ---> luci-app-upnp #通用即插即用UPnP(端口自动转发) LuCI ---> Applications ---> luci-app-usb-printer #USB 打印服务器 LuCI ---> Applications ---> luci-app-verysync #微力同步 * LuCI ---> Applications ---> luci-app-vlmcsd #KMS服务器设置 LuCI ---> Applications ---> luci-app-vnstat #vnStat网络监控(图表) LuCI ---> Applications ---> luci-app-vsftpd #FTP服务器 LuCI ---> Applications ---> luci-app-watchcat #断网检测功能与定时重启 LuCI ---> Applications ---> luci-app-webadmin #Web管理页面设置 LuCI ---> Applications ---> luci-app-webshell #网页命令行终端(已弃) LuCI ---> Applications ---> luci-app-wifischedule #WiFi 计划 LuCI ---> Applications ---> luci-app-wireguard #virtual**服务器 WireGuard状态 LuCI ---> Applications ---> luci-app-wol #WOL网络唤醒 LuCI ---> Applications ---> luci-app-wrtbwmon #实时流量监测 LuCI ---> Applications ---> luci-app-xlnetacc #迅雷快鸟 LuCI ---> Applications ---> luci-app-zerotier #ZeroTier内网穿透支持IPv6Extra packages ---> ipv6helper (选定这个后下面几项自动选择了) Network ---> odhcp6c Network ---> odhcpd-ipv6only LuCI ---> Protocols ---> luci-proto-ipv6 LuCI ---> Protocols ---> luci-proto-ppp打开适用于VMware的VM ToolsUtilities ---> open-vm-tools第二次编译:cd openwrt # 进入LEDE目录 git pull # 同步源码 ./scripts/feeds update -a && ./scripts/feeds install -a # 更新Feeds rm -rf ./tmp && rm -rf .config # 清除编译配置和缓存 make menuconfig # 进入编译配置菜单 make -jn V=99 # 开始编译 n=线程数+1,例如4线程的I5填-j5
2022年07月30日
121 阅读
0 评论
0 点赞
2022-07-23
Debian、Centos如何实现端口转发?手把手新手教程
什么是端口转发?为什么要转发?准确来讲叫流量转发,因为流量是基于端口的,所以一般称为端口转发。比如电信到伯力很差,我买了个上海联通鸡做转发,那么就是电信->联通:1200->伯力:4900,那么我访问联通的1200端口,等于访问伯力的4900端口转发还可以用于公网 frp,反代网站等用途用什么转发?推荐 iptables 或者 firewalld,都是内核级别的转发,性能损耗极少。如果用 gost/brook 等第三方工具转发,流量大或者连接数过多的时候 cpu 和负载压力变大,对于 nat 小鸡特别不友好。基于 firewalld 转发(适用于 centos7)如果 Debian 也能装 firewalld,只要能装上并正常工作,也是能用它进行转发的。以下命令都在 中转机 执行先停止iptablessystemctl stop iptables systemctl disable iptables安装,开机启动yum install firewalld systemctl start firewalld systemctl enable firewalld.service状态:显示绿色 active 说明服务运行正常systemctl status firewalld开启内核转发,然后重启echo 1 > /proc/sys/net/ipv4/ip_forward sysctl -p reboot到这里安装完成,然后直接编辑 vim /etc/firewalld/zones/public.xml 文件,这个是 firewalld 配置文件把下面的配置粘贴进去:<?xml version="1.0" encoding="utf-8"?> <zone> <short>Public</short> <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description> <service name="ssh"/> <service name="dhcpv6-client"/> <port protocol="tcp" port="10-65000"/> <port protocol="udp" port="10-65000"/> <masquerade/> <forward-port to-addr="远程ip" to-port="远程端口" protocol="tcp" port="本地端口"/> <forward-port to-addr="远程ip" to-port="远程端口" protocol="udp" port="本地端口"/> </zone>重启防火墙就生效了systemctl restart firewalld.service每次修改 public.xml 要重启防火墙才会生效基于 iptables 转发(适用于centos7,debian8+)先安装 iptables# Centos yum install -y iptables yum install -y iptables-services # Debian、Ubuntu apt-get install -y iptables apt-get install -y iptables-services设置开机启动systemctl start iptables systemctl enable iptables查看服务状态,显示 绿色 active 就可以了service iptables status清空所有防火墙规则,避免因端口没开造成影响iptables -F iptables -X开启内核转发,重启echo -e "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p reboot到这里安装完成,接下来就是添加转发规则,可以自己添加,也可以使用脚本。自己直接添加iptables -t nat -A PREROUTING -p tcp --dport [本机端口号] -j DNAT --to-destination [目标IP:端口] iptables -t nat -A PREROUTING -p udp --dport [本机端口号] -j DNAT --to-destination [目标IP:端口] iptables -t nat -A POSTROUTING -p tcp -d [目标IP] --dport [目标端口号] -j SNAT --to-source [本机主网卡IP] iptables -t nat -A POSTROUTING -p udp -d [目标IP] --dport [目标端口号] -j SNAT --to-source [本机主网卡IP]借助脚本这个脚本是帮你一键执行 iptables 命令,还是 调用 iptables,非第三方转发软件,支持ddns感谢7MU https://github.com/cimmu/scriptwget --no-check-certificate -qO natcfg.sh https://github.com/cimmu/script/raw/main/natcfg.sh && bash natcfg.sh
2022年07月23日
21 阅读
0 评论
0 点赞
2022-07-21
如何设置IntelliJ IDEA的内存和启动参数
内存分配越多,执行效果就越好。但是,除了IDEA之外,许多其他应用程序也需要消耗内存。所以,大家的目标应该是在提高性能和内存消耗之间找到一个平衡。设置方法很简单,只需要从菜单中找到:Help设置最大内存Chanage Memory Setting ,这是一个可视化的配置菜单项,用来设置IDEA的最大内存而该菜单本质其实还是往下面这个Edit Custom VM Options功能的配置文件中写其中一个参数而已。配置虚拟机参数Edit Custom VM Options,这个配置就比较通用了,用来配置IDEA运行的虚拟机各项细节参数:建议根据自己机器的最大内存和同时运行的其他软件的情况做实际调整。
2022年07月21日
13 阅读
0 评论
0 点赞
1
2
3
4
...
18