杂项(每天看到的感兴趣的)

2023-11-12

Tomcat最大承受的并发数

Tomcat的最大并发数取决于多个因素,包括硬件资源(如CPU、内存等)、网络带宽、应用程序性能以及Tomcat本身的配置。在默认情况下,Tomcat可以处理的最大并发连接数为200。

然而,在实际生产环境中,这个数字可能会受到其他限制。以下是一些影响Tomcat最大承受并发数的因素:

  1. 硬件资源:服务器的CPU和内存对Tomcat处理请求速度有很大影响。如果硬件资源不足,那么即使增加了Tomcat允许的最大连接数也无法提高其承载能力。
  2. 应用程序性能:应用程序代码质量和优化程度直接影响到每个请求所需处理时间。一个效率低下或者存在问题的应用程序可能导致整体吞吐量降低。
  3. 数据库性能:如果你使用数据库作为后端数据源,并且查询操作较慢,则会限制整体系统吞吐量。
  4. Tomcat配置参数:通过调整线程池大小、超时设置等参数来优化Tomcat以满足特定场景下需要支持更高并发连接数要求。
  5. 操作系统限制:操作系统层面也可能对TCP/IP连接数量进行限制,例如Linux上文件描述符数量上限等。

综合考虑以上因素,在实践中确定适当的并发请求数需要根据具体场景进行测试与调优。通常建议先从默认值开始,并结合压力测试结果逐步调整相关参数以达到理想状态

当tomcat达到最大线程数后,还能接受新的请求吗?

当Tomcat达到最大线程数后,它仍然可以接受新的请求。但是,这些新请求将会被放入队列中等待空闲线程可用。在此期间,如果没有足够的空闲线程来处理排队的请求,则这些请求可能会遇到延迟。

当连接队列已满时(即达到了配置中设置的最大连接数),Tomcat将拒绝任何进一步的新连接,并返回错误信息给客户端(例如HTTP 503 Service Unavailable)。

为了防止出现上述情况,在实际生产环境中需要根据应用程序性能、硬件资源和预期负载对Tomcat进行适当调优。通过增加线程池大小、提高超时限制或者优化应用程序代码等方式来确保系统能够在高并发场景下正常运行。同时,也可以考虑使用负载均衡器分散流量以减轻单个Tomcat实例承受压力。

SpringCloudBus现在还在使用吗

是的,Spring Cloud Bus仍然在使用。Spring Cloud Bus是一个用于将分布式系统中的服务连接起来并实现消息传递功能的组件。它主要用于广播配置文件更改事件、管理指令或其他需要跨多个服务实例进行通信的场景。

Spring Cloud Bus基于消息代理(如RabbitMQ或Kafka)构建,并与Spring Cloud Config Server结合使用以提供动态配置更新功能。当某个服务实例接收到新配置时,它可以通过Bus触发其他所有相关服务实例刷新其本地缓存中的配置信息。

尽管有一些新兴技术和解决方案可能会取代部分Spring Cloud Bus所涵盖的功能,但目前许多项目依然在使用这一组件作为微服务架构下统一消息总线和事件驱动通信机制。

需要注意的是,在选择是否采用Spring Cloud Bus时,请根据具体项目需求、团队经验以及整体技术栈进行评估。

令牌桶算法

一、什么是令牌桶算法?

令牌桶算法是一种流量控制策略,用于限制请求数。它通过维护一个固定容量的“令牌桶”,并以恒定速率向其中添加令牌。当请求到达时,需要从桶中取出一个令牌才能被处理;如果没有可用的令牌,则请求将被拒绝或等待

以下是使用 Java 实现的简单示例:

// 声明一个令牌桶
public class TokenBucket {
    private final int capacity; // 仓库容量
    private final AtomicInteger tokens; // 当前剩余token数量
    private final int refillRate; // 每秒补充token数

    public TokenBucket(int capacity, int refillRate) {
        this.capacity = capacity;
        this.tokens = new AtomicInteger(capacity);
        this.refillRate = refillRate;

        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        // 每隔 (1000 / refillRate) 毫秒补充一个令牌
        scheduler.scheduleAtFixedRate(() -> {
            if (tokens.get() < capacity) {
                tokens.incrementAndGet();
            }
        }, 0, 1000 / refillRate, TimeUnit.MILLISECONDS);
    }

    // 从令牌桶中消耗一个令牌
    public synchronized boolean tryConsume() {
        if (tokens.get() > 0) {
            tokens.decrementAndGet();
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws InterruptedException {
        TokenBucket tokenBucket = new TokenBucket(5, 2);
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        // 每隔1s钟,再发起三个请求, 按照令牌桶的策略,之后的每秒,每次三个请求,都会被接收2个
        scheduler.scheduleAtFixedRate(() -> {
            CountDownLatch countDownLatch = new CountDownLatch(3);
            System.out.println("--------------------------start-------------------------------------->");
            for (int i = 0; i < 3; i++) {
                threadPool.execute(() -> {
                    System.out.println(new Date() + "Request " + Thread.currentThread().getId() + ": " + (tokenBucket.tryConsume() ? "Accepted" :
                            "Rejected"));
                    countDownLatch.countDown();
                });
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {

            }
            System.out.println("--------------------------end-------------------------------------->");
        }, 0, 1000, TimeUnit.MILLISECONDS);

    }
}

在这个示例中,我们创建了一个容量为5的令牌桶,并设置每秒补充2个令牌。然后定时每秒发起3个请求,观察结果可以看到,前三秒的请求都被接收,后面所有的每秒请求,接收2个,拒绝一个

二、单个Jvm应用的限流框架

在 Java 生态中,有一些成熟的库实现了令牌桶算法,以下是两个常用的库:

Guava RateLimiter

Guava RateLimiter是一个用于限制操作速率的工具类,它可以帮助我们在需要控制某些操作频率时提供稳定的请求处理速度

public class RateLimiterDemo {

    public static void main(String[] args) {
        // 创建一个每秒允许2个令牌(即两次操作)通过的RateLimiter实例
        RateLimiter rateLimiter = RateLimiter.create(2.0);

        for (int i = 1; i <= 10; i++) {
            // 请求获取令牌,如果没有可用令牌,则阻塞等待
            if (rateLimiter.tryAcquire()) {

                System.out.println("Task " + i + " acquired");
                // 执行任务逻辑(此处为了演示效果,只打印输出)
                doTask(i);
            } else {
                System.out.println("Task " + i + " reject");
            }
        }
    }

    private static void doTask(int taskId) {
        System.out.println("Executing task: " + taskId);
    }
}

RateLimiter (支持内存和分布式)

三、分布式的限流

auth0,auth1,auth2的区别

在您的问题中,我认为您可能是想询问OAuth 1.0、OAuth 2.0以及Auth0之间的区别。以下是这三者之间的主要差异:

  1. OAuth 1.0

    OAuth 1.0是一个开放标准,用于授权第三方应用访问用户数据而无需共享密码。它使用了一种复杂的签名过程来确保请求安全,并依赖于预先共享的密钥和令牌。

    缺点:

    • 需要对每个请求进行加密签名处理
    • 不支持移动设备和本地客户端应用程序
    • 较难实现和集成
  2. OAuth 2.0

    OAuth 2.0是OAuth协议的下一代版本,解决了上述提到的OAuth 1.0中存在的问题。与OAuth 1相比,它具有更简单、更灵活且易于实现的特点。

    特性:

    • 支持多种授权类型(如:授权码、隐式授权等)
    • 使用Bearer令牌替换加密签名
    • 更好地支持移动设备和本地客户端应用程序
    • 简化了整体流程并提高了可扩展性

3.Auth0

Auth0 是一个身份验证和授权平台服务商, 提供各种身份验证功能(包括社交登录, 单点登录等) 和基于角色/权限管理系统。

特性:

  • 提供简单易用APIs 和 SDKs 来帮助开发者快速集成身份认证功能.
  • 支持多种语言和框架.
  • 可自定义规则以满足业务逻辑需求.
  • 支持企业级SSO (Single Sign-On).

总结:

  • OAuth 1.0 和 OAuth 2.0 是两个不同版本的开放标准协议,旨在允许第三方应用访问用户数据而无需共享密码。
  • Auth0 则是一个独立公司所提供服务产品, 它可以帮助你轻松实现基于诸如 OpenID Connect 或 SAML 等其他标准协议 的 身份认证与鉴权功能.

请注意,在选择合适方法时,请根据项目需求、技术栈和资源考虑因素权衡不同选项带来可能影响性能、可靠性及易用性等方面表现。

SimpleDateFormat类在Java中用于解析和格式化日期。然而,它不是线程安全的

当多个线程共享并同时访问同一个SimpleDateFormat实例时,可能会导致数据不一致或错误的结果。为了避免这种情况,您可以采取以下几种方法:

  1. 使用局部变量:每个线程创建自己的独立实例,并且只在该线程内使用。
public void formatAndParseDate(Date date) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String formattedDate = sdf.format(date);
    // ...
}
  1. 使用ThreadLocal:将SimpleDateFormat对象存储在一个ThreadLocal变量中,确保每个线程都有其自己的副本。
private static final ThreadLocal<SimpleDateFormat> threadSafeSdf =
        ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

public void formatAndParseDate(Date date) {
    SimpleDateFormat sdf = threadSafeSdf.get();
    String formattedDate = sdf.format(date);
    // ...
}

自 Java 8 起, 推荐使用 java.time.format.DateTimeFormatter: 它是线程安全的替代方案

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterDemo {

   public static void main(String[] args) {
       LocalDate date = LocalDate.now();

       DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
       String formattedDate = formatter.format(date);

       System.out.println(formattedDate);
   }
}

jdk中有哪些BlockingQueue

Java标准库中的java.util.concurrent包提供了多种实现了BlockingQueue接口的队列类。这些队列允许在插入和移除元素时进行阻塞操作,使得它们非常适合用于生产者-消费者模式等多线程场景。

以下是JDK中主要的BlockingQueue实现:

  1. ArrayBlockingQueue: 基于数组结构的有界阻塞队列。当队列满时,尝试向其中添加元素会导致操作被阻塞;同样地,当队列为空时,尝试从中取出元素也会导致操作被阻塞。
  2. LinkedBlockingQueue: 基于链表结构的可选边界(默认无边界)阻塞队列。与ArrayBlockingQueue类似,在达到容量限制或空状态下执行相应操作将导致线程被阻塞。
  3. PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列。优先级由Comparator决定或通过Comparable接口自然排序。此实现不允许使用null值,并且依赖于对象之间比较顺序来确保正确行为。
  4. SynchronousQueue: 一种特殊类型的 Blocking Queue, 其内部没有存储空间, 每个插入操作必须等待另一个线程对应进行删除(获取)操作才能成功完成, 反之亦然.
  5. DelayQueue: 是一种基于时间延迟(Delayed)元素排放顺序 的无界 队列。只有在指定延迟时间已过后才可以从该queue里面取出数据.
  6. LinkedTransferQueue(Java7引入): 是一种链表结构、FIFO(First In First Out) 排序规则并具备transfer功能 (直接将任务传给consumer而不需要经过queue缓存) 的blocking queue.

以上就是JDK中主要提供的各种类型 BlockingQueues 实现,请根据您项目需求选择合适类型以满足性能及功能需求

Maven Jar Plugin

Maven Jar Plugin是一个用于构建Java项目的Maven插件。它的主要作用是将项目编译后的字节码文件(如.class文件)和其他资源文件打包成一个JAR(Java Archive)文件,以便于分发、部署和运行。

以下是Maven Jar Plugin的一些关键功能:

  1. 生成JAR文件:根据项目中定义的源代码、资源文件和依赖项创建JAR。
  2. 设置Manifest属性:为生成的JAR设置Manifest属性,例如指定应用程序入口点(Main-Class),或者添加类路径等。
  3. 包含/排除特定内容:可以配置插件来包含或排除某些特定类型或名称模式的内容。
  4. 支持附加工件:允许在同一构建过程中创建多个不同分类器标签(classifier-tagged)版本的jar。

总之,Maven Jar Plugin使得开发人员能够轻松地将他们使用Maven构建管理工具开发并维护复杂Java应用程序时所需所有组件捆绑到单个可执行压缩档案中。

Maven Dependency Plugin

Maven Dependency Plugin是一个用于管理和操作项目依赖项的Maven插件。它提供了一系列有关依赖项处理的功能,帮助开发人员更好地控制项目中使用的库和组件。

以下是Maven Dependency Plugin的一些主要作用:

  1. 分析和显示依赖信息:可以查看项目直接或间接(传递性)引入的所有依赖项,以及它们之间的关系。
  2. 复制、解压缩和打包依赖文件:允许将指定范围内(如编译时、运行时等)的所有或部分依赖复制到特定目录;还可以解压缩已经存在本地仓库中但未被当前项目使用到的某个jar包;也支持将多个jar合并成一个单独文件。
  3. 检测冲突与重复:检查不同版本之间可能导致问题或错误结果产生的冲突,并找出哪些类在多个JAR文件中重复出现。
  4. 生成classpath字符串:根据当前项目所需创建可用于Java命令行执行程序所需类路径字符串。
  5. 清理本地仓库:删除无效且不再需要保留在本地仓库中过期快照版本,释放存储空间。

通过这些功能,Maven Dependency Plugin使得开发人员能够更轻松地管理他们使用Maven构建工具进行Java应用程序开发时涉及到各种外部资源。

为什么maven clean可以清除掉target包

Maven是一个项目构建和管理工具,它使用插件来执行各种任务。maven clean命令实际上是调用了Maven Clean插件的clean目标(goal)。

Maven Clean插件负责清理构建过程中产生的文件和目录。默认情况下,该插件会删除项目根目录下的target文件夹及其内容,因为这个文件夹通常包含编译后的类、测试报告、打包生成的JAR或WAR等临时输出结果。

当你运行 mvn clean 命令时,以下步骤将被执行:

  1. Maven解析并加载pom.xml配置文件。
  2. Maven查找Clean插件,并确定要执行哪个版本以及如何配置。
  3. 根据配置信息(例如:是否有自定义输出路径),Clean 插件定位到需要删除的目录,默认为 target 目录。
  4. Clean 插件逐层遍历并删除指定目录及其子目录中所有内容。

所以,在运行 mvn clean 后,你会发现 target 文件夹已经被清除掉了。如果需要修改默认行为或者添加额外操作,请参考 Maven Clean Plugin 官方文档 进行相应配置。

为什么maven clean可以清除掉target包

Maven是一个项目构建和管理工具,它使用插件来执行各种任务。maven clean命令实际上是调用了Maven Clean插件的clean目标(goal)。

Maven Clean插件负责清理构建过程中产生的文件和目录。默认情况下,该插件会删除项目根目录下的target文件夹及其内容,因为这个文件夹通常包含编译后的类、测试报告、打包生成的JAR或WAR等临时输出结果。

当你运行 mvn clean 命令时,以下步骤将被执行:

  1. Maven解析并加载pom.xml配置文件。
  2. Maven查找Clean插件,并确定要执行哪个版本以及如何配置。
  3. 根据配置信息(例如:是否有自定义输出路径),Clean 插件定位到需要删除的目录,默认为 target 目录。
  4. Clean 插件逐层遍历并删除指定目录及其子目录中所有内容。

所以,在运行 mvn clean 后,你会发现 target 文件夹已经被清除掉了。如果需要修改默认行为或者添加额外操作,请参考 Maven Clean Plugin 官方文档 进行相应配置。

Java面试感觉知识点太多记不住怎么办

面试Java职位时,确实需要掌握许多知识点。如果觉得难以记住所有内容,请尝试以下策略来提高你的学习效果和应对面试:

  1. 了解基本概念:首先要熟练掌握Java语言的基础知识,如数据类型、运算符、流程控制、类与对象等。这些是其他高级主题的基础。
  2. 制定学习计划:将知识点分为不同模块,并按照优先级进行安排。例如,可以从核心技术(如集合框架、多线程)开始,再逐渐扩展到Web开发、数据库操作等领域。
  3. 实践项目经验:通过参与实际项目或编写个人作品来巩固所学知识。在实际应用中遇到问题并解决它们会加深理解。
  4. 查阅文档和教程:阅读官方文档及权威教材以获取详细信息;同时也可关注博客文章和在线教程来拓展视野。
  5. 创建自己的笔记系统:整理归纳所学内容,并形成一套属于自己的笔记体系。这有助于回顾复习并查找相关资料。
  6. 参加技术社区活动:加入开发者论坛或社交平台群组,在其中提问、回答问题并分享经验心得。这样既能够检验自己水平,又能从他人身上获得启示。
  7. 模拟面试环境:向朋友请教或使用在线模拟面试工具进行练习。了解常见问题类型,并针对性地准备答案。
  8. 定期复习总结: 周期性地回顾已学过的内容, 并尝试总结归纳规律性原则, 提高应变能力.

9.保持积极态度: 面对众多知识点时, 不要气馁, 要相信只要付出足够努力就一定会取得进步.

最后,请注意调整好心态,把每次面试当作是一个锻炼和学习的机会。即使没有成功,也可以从中总结经验教训,并为下一次面试做好准备。

8-29 动态代理复习,cglib代理复习

Spring

Spring如何解决循环依赖问题

Spring框架通过使用依赖注入(Dependency Injection, DI)和单例模式解决循环依赖问题。具体来说,它采用了以下方法:

  1. 三级缓存:在创建bean的过程中,Spring容器维护了三个缓存Map结构:
    • singletonObjects:一级缓存,用于保存已经完全初始化完成的单例bean。
    • earlySingletonObjects:二级缓存,用于保存正在创建过程中但尚未完全初始化完成的早期单例bean。
    • singletonFactories:三级缓存,用于保存原始的BeanFactory对象。
  2. 提前暴露引用:当一个bean正在被创建时(即实例化后、属性填充之前),Spring会将这个尚未完全初始化完成的早期bean放入二级缓存,并将其对应的BeanFactory对象放入三级缓存。这样,在处理循环依赖时就可以从二级或者三级缓存获取到相互依赖的其他bean。
  3. 懒加载:如果某些情况下无法避免循环依赖问题(例如涉及到prototype作用域或者有AOP代理等复杂场景),可以考虑使用懒加载策略。通过为相关类添加@Lazy注解或在XML配置文件中设置lazy-init="true"属性,可以使得该类只在首次被调用时才进行实际初始化操作。

举一个简单示例说明如何解决循环依赖:‘

@Service
public class A {
    @Autowired
    private B b;
}

@Service
public class B {
    @Autowired
    private A a;
}

上述代码存在A和B两个服务类相互引用对方导致循环依赖。由于默认情况下所有@Service标记的组件都是singleton作用域,在此场景下Spring会自动处理并解决这种循环依赖问题。

总之,在大多数常见场景下,Spring框架能够自动识别并妥善处理循环依赖问题。然而,在某些特殊情形下可能仍需开发人员手动干预以确保系统正常运行

Spring如何通过三级缓存来解决循环依赖问题

Spring通过三级缓存来解决循环依赖问题的关键在于提前暴露一个尚未完全初始化完成的bean引用。这使得其他正在创建过程中且与之存在循环依赖关系的bean可以获取到该引用,从而打破循环依赖。

以下是Spring如何使用三级缓存解决循环依赖问题的详细步骤:

  1. 当容器开始实例化一个新的singleton bean(例如BeanA)时,首先会调用其构造方法创建一个原始对象。
  2. 在进行属性填充之前,将此原始对象放入二级缓存(earlySingletonObjects)并将其对应的BeanFactory对象放入三级缓存(singletonFactories)。这样一来,在还没有完成所有属性注入和初始化操作之前就已经为其他bean提供了对BeanA的访问途径。
  3. 接下来进行属性填充。假设在处理BeanA时发现它有一个对另一个单例bean(例如BeanB)的引用。由于我们还没有完成设置BeanA,因此需要先去实例化、配置并添加好相关引用后才能继续处理。
  4. 容器开始实例化和配置 BeanB,并注意到它也有一个指向 BeanA 的引用。然而此刻由于已经有了早期暴露出来尚未完全初始化完成但可供访问使用的 BeanA 引用,所以不会再次触发 BeanA 的创建过程。相反地,直接从二级或者三级缓存中获取到该早期版本即可避免死锁现象。
  5. 一旦成功设置好了 BeanB 中对应指向 BeanA 的字段值,则表明两者间存在循环依赖关系已被正常处理完毕。随后可以回头继续执行剩余部分以最终完成整个流程。

总结起来说:通过利用三级缓存机制及提前暴露尚未完全初始化完成但足够支持进一步操作需求的bean引用方式,Spring框架有效地解决了单例作用域下可能出现死锁等问题导致无法正常运行风险。

需要注意:上述描述仅针对默认情况下 singleton 作用域内 bean 对象;如果涉及 prototype 或其他作用域,可能需要额外手动处理以确保系统正常运行。

Kafka

如果kafka topic有多个分区,但是消费者组只有一个消费者,那么它该如何消费

当Kafka topic有多个分区,但消费者组只有一个消费者时,这个单一的消费者将会负责处理所有分区中的消息。具体来说:

  1. 消费者订阅了包含多个分区的topic。
  2. Kafka会为每个分区指定一个消费者(在本例中只有一个),并建立起它们之间的映射关系。
  3. 由于只有一个消费者,所以它需要依次从各个分区拉取数据进行处理。通常情况下,这种顺序是轮流进行的:先从第一个分区获取一批消息、处理完毕后再去第二个分区获取另一批消息,如此循环直至完成所有任务。

虽然在这种场景下仍能正常运行并保证消息被成功处理,但可能无法充分发挥Kafka天然支持高并发和负载均衡等特性带来优势。因此,在实际应用过程中建议根据需求调整相应参数设置以提升系统性能表现。

例如:

  • 增加更多消费者:可以通过添加新成员到同一消费组内或创建额外独立组别方式实现;请注意确保总数不超过可用主题分区数量避免资源浪费。
  • 调整主题配置:根据业务需求重新规划合适数量及策略等相关参数值,并结合其他方案共同作用达到最佳效果。

综上所述,在面临类似问题时,请务必全面评估当前系统状态及潜在风险,并采取恰当措施解决以确保稳定运行。

为什么消费者组中的每个消费者不能消费相同的分区

在Kafka中,消费者组(Consumer Group)的设计目的之一是为了实现负载均衡。通过将一个topic的分区分配给不同的消费者,可以并行地处理消息以提高整体吞吐量。因此,在一个消费者组内,每个分区只能被一个消费者所消费。

以下是为什么每个消费者不能同时消费相同分区的原因:

  1. 负载均衡:如前所述,Kafka使用Consumer Group来实现负载均衡。如果允许多个消费者同时处理同一分区,则会破坏这种平衡,并可能导致某些节点过载而其他节点空闲。
  2. 避免重复处理:当多个消费者同时从相同分区读取消息时,可能会出现重复处理消息的情况。这样就无法保证“至少一次”或“精确一次”语义。
  3. 顺序保证:Kafka可以确保单个分区内消息按照它们产生时先后顺序进行存储和传递。但如果有多个并发操作针对相同数据源,则很难维护全局排序状态;尤其涉及到跨越网络、硬件等环境差异性更加困难。
  4. 简化偏移量管理:在Kafka中,每个consumer需要跟踪自己当前正在读取哪条记录(即offset)。如果允许多个consumer共享一个partition,则必须引入额外机制来协调他们之间关于offset追踪与更新问题;反之则可大幅降低系统复杂度。

总结起来说,在Kafka中限制每个consumer group内部成员只能唯一对应特定主题下某具体partition资源既符合设计初衷也有利于优化运行效果。当然,在实际应用场景下请根据需求灵活选择恰当方案以满足业务要求。

kafka的max.in.flight.requests.per.connection配置为什么可以保证生产者生产消息的有序性

Kafka 生产者的 max.in.flight.requests.per.connection 配置参数用于控制生产者在等待服务器响应之前可以发送到同一分区的未确认请求(in-flight requests)的最大数量。这个参数限制了每个连接上允许同时进行多少个并行请求。

当将 max.in.flight.requests.per.connection 设置为 1 时,它可以保证生产者生产消息的有序性,原因如下:

  1. 串行处理:将此配置设置为 1 意味着 Kafka 生产者会在收到当前消息成功写入后才能发送下一条消息。这样就确保了对于给定分区来说,在任何时刻只有一个 in-flight 请求。由于没有其他并发请求,所以不需要担心顺序问题。
  2. 重试和幂等性:如果启用了幂等性(通过设置 enable.idempotence=true),默认情况下 max.in.flight.requests.per.connection 的值会被限制为5。这是因为 Kafka 可以使用其内部机制来确保即使发生重试操作也能够维持有序状态;然而,在非幂等模式下,如果要求严格按照顺序发送消息,则需要将该配置设置为1。
  3. 错误处理:当某条消息失败时,由于只允许一个 in-flight 请求,Kafka 生产者会阻塞直至解决问题或触发异常处理流程。这种方式避免了出现乱序情况,并确保消费端接收到正确顺序的数据。

请注意,在实际应用场景中,请根据需求灵活选择恰当方案以满足业务要求。例如,在关注吞吐量优先级更高、可容忍轻微乱序情况下,则可以适当增加 max.in.flight.requests.per.connection 参数值。

kafka的leo和hw

在 Kafka 中,LEO(Log End Offset)和 HW(High Watermark)是与副本管理和消息消费相关的两个重要概念。

  1. LEO (Log End Offset):LEO 是指分区中每个副本日志的末尾偏移量。换句话说,它表示当前副本已写入的最后一条消息的下一个位置。当生产者向某个分区发送新消息时,该消息将被追加到所有副本的 LEO 位置,并且各自 LEO 随之增加。请注意,在 Kafka 的 ISR(In-Sync Replicas, 同步副本集合)机制下,只有那些保持与主题领导者同步状态、满足特定条件限制的 follower 副本才会被视为有效。

  2. HW (High Watermark):HW 是指对于给定分区来说,在此偏移量之前(包括此偏移量)所有数据都已经成功复制到了至少 min.insync.replicas 数目配置值所规定数量以上的其他 follower 副本上。简而言之,HW 标记了可以安全地认为已经提交并可供消费者读取数据范围内最大边界点。

    在正常情况下,Kafka 消费者仅能够读取位于 HW 以内部分数据;这样就确保了只有在多数副本确认接收后才允许消费者获取消息,从而提高了数据持久性和一致性。同时,在领导者副本发生故障、需要重新选举时,HW 也起到关键作用:新的领导者将基于各个 follower 副本 HW 情况来确定最终可靠状态。

总之,LEO 和 HW 是 Kafka 系统中两个核心概念,它们分别代表了副本日志末尾位置以及已提交并可供消费的消息边界点。通过协同工作,这两个指标有助于确保 Kafka 高效、稳定地运行。

Spring-kafka中为什么消费者会(Re-)joining group

在 Spring-Kafka 中,消费者可能会因为以下原因触发 “(Re-)joining group” 操作:

  1. 新的消费者加入:当一个新的消费者实例启动并加入到现有的消费者组时,Kafka 需要重新平衡分区所有权以确保负载均匀地分配给各个成员。这将导致整个组中的所有消费者暂停处理,并重新参与组内协调过程。
  2. 现有消费者离开:类似地,当一个现有的消费者实例关闭或意外断开连接(例如由于网络故障)时,Kafka 也需要对剩余成员进行再次平衡操作。
  3. 主题元数据变更:如果 Kafka 集群中某个主题发生了元数据变更(如新增/删除分区),那么订阅该主题的所有相关消费组都需要重新计算分区归属关系。
  4. 心跳超时:每个 Kafka 消费者都定期向协调器发送心跳消息以表示其活跃状态。如果某一时间段内未收到特定成员心跳,则协调器会认为该成员已失效,并触发整体重平衡过程。请注意,在高延迟、繁忙系统环境下,频繁出现此类情况可能导致不稳定性。为避免此问题,可以尝试调整 session.timeout.msmax.poll.interval.ms 参数值。
  5. 手动触发重平衡:在某些特定场景下,您可能需要通过编程方式强制执行消费者组内的重新平衡操作。例如,在 Spring-Kafka 中,可以使用 KafkaConsumer#unsubscribe() 或者更改订阅主题列表等方法实现该目标。

总之,在 Spring-Kafka 中,消费者可能会因为多种原因而触发 “(Re-)joining group” 操作。这是 Kafka 保持负载均衡、确保数据一致性所必需的自我调整过程

kafka消费者再平衡的过程中,消息会丢失吗

在 Kafka 中,消费者再平衡(rebalance)是指分区重新分配给消费者组中的不同消费者实例。这通常发生在以下情况:

  1. 新的消费者加入到消费者组。
  2. 消费者离开或从组中移除。
  3. 主题的分区数发生变化。

Kafka 的设计确保了即使在再平衡过程中,消息也不会丢失。当再平衡开始时,所有涉及到的消费者都会停止读取消息并提交它们当前处理到的偏移量(offset)。然后,协调器将重新计算每个分区应该被哪个消费者处理,并通知相关的消费者。一旦新的分配方案确定下来,各个消费者就可以从上次提交的偏移量处继续读取和处理消息。

需要注意,在再平衡期间可能会出现短暂延迟,因为此时所有涉及到重分配操作的 Kafka 分区都无法进行数据传输。但是,在整个过程中 Kafka 仍然能够保证消息不丢失以及“至少一次”(at-least-once)语义。

尽管如此,在某些场景下还是有可能遇到重复处理相同消息或跳过部分未处理消息等问题。要解决这类问题,请确保您正确地配置了自动提交偏移量、设置合适大小缓存以减小网络延迟影响、使用幂等性写入操作等策略来提高系统可靠性。

spring-boot-starter-parent这个starter的作用

spring-boot-starter-parent 是一个特殊的 starter,它主要用于提供 Spring Boot 项目的默认配置和依赖管理。这个 starter 并不直接提供任何实际功能,而是作为一个基础模板来简化其他 Spring Boot starters 的使用。

当你在项目中引入 spring-boot-starter-parent 时,它会自动应用以下几方面的内容:

  1. 默认插件配置:例如 Maven 插件(如 spring-boot-maven-plugin)和其他常用插件(如 surefire、compiler 等)的默认版本和配置。
  2. 默认依赖管理:通过 <dependencyManagement> 标签定义了一系列与 Spring Boot 相关的库及其兼容版本。这样,在添加具体功能时只需指定对应 starter 而无需关心具体版本。
  3. 默认属性值:包括 Java 版本、编码方式等通用属性设置。
  4. 基本资源过滤:支持将 ${..} 占位符替换为相应属性值。

总之,spring-boot-starter-parent 提供了一套统一且合理的默认配置,使得开发者能够更轻松地创建和维护 Spring Boot 项目。同时,如果需要自定义某些设置或覆盖默认行为,也可以在子项目中进行调整。

commons-lang这个依赖的作用

commons-lang 是一个 Java 库,提供了许多实用的工具类和方法,以帮助开发者更方便地处理一些常见的编程任务。它是 Apache Commons 项目的一部分,主要关注于操作字符串、数字、日期时间等基本数据类型。

以下是 commons-lang 中一些典型功能:

  1. 字符串操作:例如判断空白(null 或空字符串)、连接、替换、截取等。
  2. 数字操作:例如随机数生成、进制转换等。
  3. 日期时间操作:例如格式化、解析、比较及计算间隔等。
  4. 对象工具:例如创建哈希码(hashCode)、比较对象(equals)或执行深拷贝(clone)等。
  5. 系统属性获取:如用户目录路径或临时文件夹路径等。

引入 commons-lang 可以简化代码并减少重复性工作,使得开发过程更加高效。需要注意的是,在使用 Spring Boot 时,很多这些功能已经被其他库如 Spring 工具类或 Java 标准库所提供。因此,在选择使用 commons-lang 前,请确保你确实需要其中提供的特定功能,并评估是否有现有可用资源可以满足需求。

Spring可以在任何一个类上面加上@Transaction注解吗

在 Spring 中,你可以在任何类的方法上添加 @Transactional 注解来声明该方法需要进行事务管理。然而,并非所有类都能支持这个注解。

要使 @Transactional 注解生效,必须满足以下条件:

  1. 类或其所属的包被 Spring 扫描到并作为 Bean 管理。通常通过使用 @ComponentScan 或其他相关注解(如 @SpringBootApplication)实现。
  2. 类应当是一个 Spring Bean,即由 Spring 容器负责创建和管理。如果直接使用 Java 的关键字 new 创建对象,则无法享受到事务管理功能。
  3. 代理模式:Spring 默认采用 JDK 动态代理或 CGLIB 代理来拦截带有 @Transactional 注解的方法调用。对于实现了接口的类,默认会使用 JDK 动态代理;否则会尝试使用 CGLIB 代理。因此,请确保目标类适合生成相应类型的代理。

除了以上条件外,在某些情况下还需注意以下问题:

  • 如果目标类中存在嵌套调用(即一个方法内部调用另一个带有 @Transactional 的方法),默认情况下只有最外层的事务才会生效。若需要改变这种行为,请考虑配置不同传播级别(propagation level)。
  • 当多个数据源时,可能需要指定具体哪个数据源参与事务处理。

总之,在满足一定条件下,你可以在任何符合要求的类上加入 @Transaction 注解以启用事务管理功能。但请确保遵循正确规范,并根据项目需求进行相应配置和优化。

commons-io依赖的作用

commons-io 是 Apache Commons 项目的一部分,它是一个 Java 库,提供了许多实用功能以简化文件和流操作。这个库包含了大量与输入/输出(I/O)相关的工具类和方法,使得开发者能够更容易地处理文件、目录、字符集编码等 I/O 操作。

以下是 commons-io 的一些主要特性:

  1. 文件操作:复制、移动、删除文件或目录;读取文件内容;监视文件变化等。
  2. 输入/输出流操作:将 InputStream 转换为 OutputStream 或 Reader 转换为 Writer 等。
  3. 字符集编码支持:自动检测文本文件的字符集编码并进行转换。
  4. 过滤器:根据名称、大小或其他条件过滤出指定的 File 对象。
  5. 工具类:提供方便使用的静态方法来执行常见 I/O 操作。

在 Java 项目中添加 commons-io 依赖可以帮助您减少手动处理底层 I/O 操作所需的代码量,并降低因错误处理导致的 bug 风险。例如,在 Maven 项目中添加如下依赖即可引入 commons-io

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

请注意替换 <version> 标签内版本号为最新发布版本。

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true

这个警告信息表明您的应用程序中存在循环依赖,Spring Boot 建议您避免使用循环依赖。要解决此问题,可以采取以下步骤:

  1. 检查代码并消除循环依赖:首先尝试找到导致循环依赖的 Bean,并重新设计它们以消除相互引用。这可能涉及将共享逻辑移动到单独的类或服务中,或者调整类之间的关系。

  2. 使用懒加载(Lazy Initialization):如果无法完全消除循环依赖,则可以考虑为其中一个 Bean 使用懒加载。在 Spring 中,可以通过 @Lazy 注解实现懒加载。例如:

    @Autowired
    @Lazy
    private SomeBean someBean;
    
  3. 启用允许循环引用:作为最后手段,您可以设置 spring.main.allow-circular-referencestrue 以允许 Spring 自动处理循环引用。但请注意,这不是推荐做法,并且可能会导致未预期的行为和性能问题。

要启用此选项,请在 application.propertiesapplication.yml 文件中添加以下配置:

  • application.properties:

    spring.main.allow-circular-references=true
    
  • application.yml:

    spring:
      main:
        allow-circular-references: true
    

建议优先考虑前两种方法来解决问题,并确保代码质量与设计规范性。仅当其他方法都无法解决时才选择启用允许循环引用功能。

SpringBoot解决跨域问题

在 Spring Boot 应用中解决跨域问题,可以使用以下方法:

  1. 全局 CORS 配置:通过实现 WebMvcConfigurer 接口并覆盖其 addCorsMappings() 方法来为整个应用添加全局 CORS 配置。

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*") // 允许任何来源的请求。请根据实际需求修改。
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的 HTTP 请求方法。
                    .allowCredentials(true) // 是否允许携带凭据(如 cookies)进行跨域请求。
                    .maxAge(3600); // 缓存预检请求响应的时间(秒)。这将减少对服务器的重复请求次数。
        }
        
    }
    
  2. 基于注解的 CORS 配置:如果您只需要为特定控制器或处理程序方法启用跨域支持,可以使用 @CrossOrigin 注解。

    在类级别上添加此注解以启用该控制器下所有处理程序方法的跨域能力:

    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @CrossOrigin(origins = "*") // 请根据实际需求修改允许来源列表。
    public class MyController {
        ...
    }
    
  3. CORS 过滤器:创建一个自定义过滤器来处理所有进入应用程序的 HTTP 请求,并在其中设置适当的响应头以允许跨域请求。

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CorsFilter implements Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*"); 
response.setHeader("Access-Control-Allow-Methods",
"POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age",
"3600");
response.setHeader(
"Access-Control-Allow-Headers",
"x-requested-with");

chain.doFilter(req,
res);
}

}

然后,在配置文件中注册此过滤器:

@Configuration

public class AppConfig {

@Bean

public FilterRegistrationBean corsFilterRegistration() {
FilterRegistrationBean registration =
new FilterRegistrationBean();
registration.setFilter(new CorsFilter());
registration.addUrlPatterns("/*");
registration.setName("corsFilter");
return registration;
}
}

请注意,在实际生产环境中启用 CORS 支持时务必谨慎配置相关参数以确保安全性。仅允许已知可信任来源发起跨域请求,并限制暴露给外部的 API 和资源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

杂项(每天看到的感兴趣的) 的相关文章

  • gsoap学习笔记一

    本文章是对gsoap中生成的cpp类型的代码框架的应用 因为要实现一些ONVIF规范中的一些功能 所以选择了gsoap生成代码框架 但是发现好多博客上都是生成的C的代码框架 使用起来很麻烦 而且引用插件功能的时候 什么时候需要修改文件内容
  • vim

    three basic mode of vim command mode also is default mode all the alphanumeric keys are bound to commands Typing dd will
  • centos 7.7.1908上隐藏顶栏和任务栏

    centos 7 7 1908上隐藏顶栏和任务栏 起因 业务需求 要求客户端软件全屏显示 禁止用户操作其他界面 1 隐藏任务栏 删除 usr share gnome shell extensions window list gnome sh
  • 远程桌面的端口设置和原理探究

    在上一篇文章外网远程控制局域网内主机 路由器端口转发设置 文章中我提到了远程连接的基本原理 本文来验证一下 并且看看怎么来修改远程连接的默认端口 首先 在被控机上开启 允许远程连接 那么内部远程控制程序就监听了3389端口 主控端发起远程连
  • 定时删除某目录下几天前的文件

    系统每天生成日志 为了保证系统正常运行 需要不断清理系统空间 就把这种事情交给批处理文件来吧 这种方法简单实用 你只要通过任务计划和批处理文件就能实现 1 任务计划 进入 控制面板 任务计划 然后根据提示选择要运行的程序 运行时间即可 2
  • xml入门

    什么是 XML XML 即可扩展标记语言 Extensible Markup Language 是一种平台无关的表示数据的方法 简单地说 使用 XML 创建的数据可以被任何应用程序在任何平台上读取 甚至可以通过手动编码来编辑和创建 XML
  • c语言之矩阵

    矩阵作为线性代数核心内容之一也是刷题人时常会遇到的一种类型 本篇博客简单介绍一下矩阵转置 上三角矩阵以及杨氏矩阵 1 转置矩阵 输入m行n列的矩阵以n行m列的方式打印出来 只要将数组的行列进行交换即可 并不难想也不难写 相应练习 牛客网BC
  • 如何提高for循环的效率--兆易创新一面

    1 实例化变量放在循环外 include
  • CodeMirror用户手册

    用户手册和参考指南版本5 46 1 CodeMirror是一个代码编辑器组件 可以嵌入到Web页面中 核心库仅提供编辑器组件 不提供伴随按钮 自动完成或其他IDE功能 它确实提供了丰富的API 在此基础上可以直接实现这些功能 有关额外功能的
  • TypeError: Cannot interpret ‘<attribute ‘dtype‘ of ‘numpy.generic‘ objects>‘ as a data type

    原因 numpy 和pandas 版本不一致 参考链接 numpy和pandas升级 pip升级 pandas失败解决
  • 循环获取Java中泛型T的属性以及属性值

    利用 Java 的反射机制来获取泛型类中的属性及其对应的值 具体实现方式如下 import java lang reflect Field public class GenericClassUtil
  • wsl Hyper-V 与 安卓模拟器虚拟机同时共存方案

    最新消息 雷电9 0版本 已经支持共存了 不必搞那么麻烦了 WSL 在开发者手里是必不可少的 仿真服务器开发模式 安卓虚拟机 有时调试起来更加方便 但可惜的是 市面上的安装模拟器 都不支持与wsl友好共存 要么是版本低 要么是卡到要死 既然
  • VMware Workstation Pro 16 安装win7

    本文使用U盘工具创建 至于为什么安装win7 毕竟很多游戏在win10已经没法玩了 1 创建虚拟机 典型创建即可 2 添加硬盘 SCSI类型 使用物理磁盘 物理驱动2 使用整个磁盘 这里的驱动2就是U盘 创建完成 这时候应该是正在使用该设备
  • 一张图正则表达式

    一张图正则表达式
  • (转)C++模板函数和重载

    C 模板函数和重载 先来看一个例子 include
  • 在Padavan上搭建udp53踩坑总结

    弄了差不多一下午 翻阅了许多帖子都没有能用的解决办法 人又不在家全程远程解决 希望对有相同需求的朋友有帮助 坑一 对于dnsmasq占用53端口的问题 查阅dnsmasq配置手册之后发现 在 etc dnsmasq conf中port缺省的
  • 解决word页码混乱并使页码从指定页开始

    解决word页码混乱并使页码从指定页开始 1 解决word页码混乱 页码混乱是由于误加了分节符导致的结果 导致页码不按照物理顺序排序 因此 我们在大纲模式下删除所有分节符 重排页码 2 从指定页重排页码 在指定页页眉位置点击布局 选择分隔符
  • 零信任架构

    零信任架构 参考文章 基于SDP技术构建零信任安全 怎样实现零信任安全架构 什么是零信任 物理边界曾经是可信网络和不可信网络之间的有效分割 防火墙通常位于网络的边缘 基于静态策略来控制网络流量 位于防火墙内部的用户会被授予高信任等级来访问企
  • 记 asp.net core 开发过程中的错误

    mysql数据库 ef进行 update database 时 报 An error occurred using the connection to database on server localhost 3307 错误原因 serve
  • C++零散易错点总结

    对日常做题中遇到的一些零散的易错点的总结 持续更新ing 1 string的length方法返回的是无符号数 当与负数比较时需要强制类型转换 否则会报错 1

随机推荐

  • js判断object里面是否包含某一字段

  • Arduino IDE闪退解决办法

    打开Arduino的时候 开始界面只显示了 初始化包 和 准备开发板 然后开始界面消息 Arduino也不能运行 解决办法 将 C Users 你的用户名 AppData Local Arduino15文件夹 删除即可 需要注意 有的电脑有
  • 代码质量检测-Sonar

    一 Sonar简介 sonarqube系统是一个代码质量检测工具 由以下四个组件组成 https docs sonarqube org display SONAR Architecture and Integration 1 一个sonar
  • JVM--调优--04--案例02--大SQL导致内存溢出

    JVM 调优 04 案例02 大SQL导致内存溢出 1 现象 项目启动 且没有人使用 一段时间后就报redis连接异常 1 1 日志信息 org redisson client RedisTimeoutException Command e
  • python教程-Python快速教程

    作者 Vamei 出处 http www cnblogs com vamei 欢迎转载 也请保留这段声明 谢谢 怎么能快速地掌握Python 这是和朋友闲聊时谈起的问题 Python包含的内容很多 加上各种标准库 拓展库 乱花渐欲迷人眼 我
  • 1500*B. Coloring(找规律&鸽巢原理)

    include
  • STM32-GPIO介绍

    目录 1 概述 2 GPIO工作原理 2 1 保护二极管及上下拉电阻 2 2 GPIO工作模式 2 2 1 浮空输入模式 2 2 2 上拉输入模式 2 2 3 下拉输入模式 2 2 4 模拟输入模式 2 2 5 开漏输出模式 2 2 6 开
  • 使用python实现微信小程序自动签到

    学校 重庆财经职业学院 学院 应用技术学院 专业班级 大数据技术与应用05班 名字 吴雨璇 指导老师 张彤老师 一 使用python实现微信小程序自动签到意义 1 首先对于咱们的APP有很大的作用 那就是当用户点击签到以后 平台就有那么多用
  • 基于梯度的优化算法

    梯度下降优化算法 大多数学习算法都涉及到优化 优化是指改变 x 以最小化或者最大化某个函数 f x 的过程 通常我们所说的优化算法都是指最小化的过程 因此 最大化的过程可以通过最小化 f x 来实现 导数是指某个函数 f x 在某一点上的斜
  • 有趣的数学 数学建模入门二 一些理论基础

    一 什么是数学建模 现实世界中混乱的问题可以用数学来解决 从而产生一系列可能的解决方案来帮助指导决策 大多数人对数学建模的概念感到不舒服 因为它是如此开放 如此多的未知信息似乎令人望而却步 哪些因素最相关 但正是现实世界问题的这种开放性导致
  • 文件索引习题

    1 设文件索引结点中有8个地址项 每个地址项大小为4字节 其中5个地址项为直接地址索引 2个地址项是一级间接地址索引 1个地址项是二级间接地址索引 磁盘索引块和磁盘数据块大小均为1KB 则可表示的单个文件最大长度是多少KB 解 磁盘索引块为
  • Linux基础命令练习题附答案解析(一)

    1 在 Linux 系统的 vi 编辑器中 如果不保存对文件进行的修改 强制退出 vi 编辑器的命令是 A q B wq C q D q 表示切换到命令模式 以在最底一行输入命令 q quit 表示退出 vi w write 表示保存文件
  • C#实现Omron欧姆龙PLC的Fins Tcp协议[转]

    转自 https blog csdn net yxt99 article details 79984153 commentBox 感谢作者 yxt99 欧姆龙PLC的FINS协议解释 UDP访问方式 读取示例 读取DM区20个字 从DM10
  • 解决openwrt opkg内核版本不匹配问题

    假设安装软件时提示需要5 4 65版本的内核 然而 系统的内核时5 4 52 root Openwrt uname a Linux Openwrt 5 4 52 0 SMP Thu Jul 23 12 16 45 2020 x86 64 O
  • opengl-shader学习笔记:varying变量

    varying变量可以在Vertex Shader和Fragment Shader之间传递数据 渲染管线中应用程序调用openglAPI 把顶点数据传给Vertex Shader Vertex Shader处理完后输出数据给Fragment
  • javaWeb基础二:Servlet(java前后端交互的技术)

    2 Servlet 2 1 定义 Servlet是sun公司提供的一门用于开发动态web资源的技术 可以实现和客户端的交互 接收客户端请求和给客户端返回响应 Sun公司在其API中提供了一个servlet接口 用户若想开发一个动态web资源
  • 获取id_rsa.pub和id_rsa.pub的作用

    SSH SSH为Secure Shell的缩写 由IETF的网络小组 Network Working Group 所制定 SSH为建立在应用层基础上的安全协议 SSH是目前较可靠 专为远程登录会话和其他网络服务提供安全性的协议 利用SSH协
  • Ubuntu 20.04 搭建NFS server

    文章目录 一 测试环境 二 安装 NFS server 一 测试环境 Ubuntu 20 04 64位 二 安装 NFS server 执行以下命令 sudo apt get install nfs kernel server 出现报错 从
  • C Primer Plus 第一章编程练习

    第一章 1 13编程练习 题 目 你刚被MacroMuscle有限公司聘用 该公司准备进入欧洲市场 需要一个把英尺单位转换为厘米单位 1英寸 2 54厘米 的 程序 该程序要提醒用户输入英寸值 你的任务是定义程序 目标和设计程序 编程过程的
  • 杂项(每天看到的感兴趣的)

    Tomcat最大承受的并发数 Tomcat的最大并发数取决于多个因素 包括硬件资源 如CPU 内存等 网络带宽 应用程序性能以及Tomcat本身的配置 在默认情况下 Tomcat可以处理的最大并发连接数为200 然而 在实际生产环境中 这个