一个带连接池的sftp客户端

sftp-spring-boot-starter

介绍
 基于jsch简单封装,并提供连接池功能,使用简单,基于SPI机制,实现定制化。
软件架构
安装教程
             <!--sftp-->
            <dependency>
                <groupId>com.javacoo</groupId>
                <artifactId>sftp-spring-boot-starter</artifactId>
                <version>1.0.0</version>
            </dependency>
使用说明
#1:配置,如
#客户端1
sftp.clients.client1.host = 127.0.0.0
sftp.clients.client1.port = 22
sftp.clients.client1.username = taskftp
sftp.clients.client1.password = 1111111
sftp.clients.client1.path = /opt/upload/

#:2:调用
    /** SFTP 客户端*/
    @Autowired
    private SftpClient sftpClient;

    /**
     * 文件传输
     * <li>上传文件到sftp服务器传输</li>
     * @author duanyong@jccfc.com
     * @date 2020/5/15 11:14
     * @param channel: 渠道ID
     * @param fileName: 文件名
     * @param inputStream: 待上传的文件输入流
     */
    public void transFile(final String channel,final String fileName, final InputStream inputStream){
        sftpClient.run(channel,sftpTemplate->{
            sftpTemplate.upload(fileName,inputStream);
        });
    }

        /**
         * 判断文件是否存在
         * <li>指定sftp文件路径和文件名,判断改文件是否存在当前指定的sftp目录下,若存在返回true,否则返回false</li>
         * @author duanyong@jccfc.com
         * @date 2020/5/15 13:51
         * @param channel:渠道ID
         * @param sftpDir:sftp目录
         * @param fileName:文件名
         * @return: boolean
         */
        public boolean exists(String channel, String sftpDir, String fileName) throws Exception {
            return sftpClient.runAndReturn(channel,sftpTemplate->{
                try {
                    sftpTemplate.cd(sftpDir);
                } catch (SftpClientException exception) {
                    if (ChannelSftp.SSH_FX_NO_SUCH_FILE == exception.id) {
                        log.info("目录不存在...新建目录:{}",sftpDir);
                        sftpTemplate.mkdirs(sftpDir);
                        return false;
                    }
                }
                if (sftpTemplate.isExist(fileName)) { // 文件是否存在
                    log.info("{}文件存在...",fileName);
                    return true;
                }
                return false;
            });
        }

### 配置参数说明

   /**
     * 池配置
     */
    @NestedConfigurationProperty
    private Pool pool = new Pool();

    /**
     * sftp服务器配置
     */
    private Map<String, SftpClientConfig> clients = new LinkedHashMap<>();

sftp服务器配置

    /**
     * 主机ip
     */
    private String host;
    /**
     * 端口号
     */
    private int port = 22;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 路径
     */
    private String path;


pool 池配置

        /**
         * 对象最大数量
         * 默认值是8
         */
        private int maxTotal = DEFAULT_MAX_TOTAL;
        /**
         * 最大空闲对象数量
         * 默认值是8
         */
        private int maxIdle = DEFAULT_MAX_IDLE;
        /**
         * 最小空闲对象数量
         * 默认值是0
         */
        private int minIdle = DEFAULT_MIN_IDLE;
        /**
         * 对象池存储空闲对象是使用的LinkedBlockingDeque,它本质上是一个支持FIFO和FILO的双向的队列,
         * common-pool2中的LinkedBlockingDeque不是Java原生的队列,而有common-pool2重新写的一个双向队列。
         * 如果为true,表示使用FIFO获取对象。
         * 默认值是true
         */
        private boolean lifo = DEFAULT_LIFO;
        /**
         * common-pool2实现的LinkedBlockingDeque双向阻塞队列使用的是Lock锁。
         * 这个参数就是表示在实例化一个LinkedBlockingDeque时,是否使用lock的公平锁。
         * 默认值是false
         */
        private boolean fairness = DEFAULT_FAIRNESS;
        /**
         * 当没有空闲连接时,获取一个对象的最大等待时间。如果这个值小于0,则永不超时,一直等待,直到有空闲对象到来。
         * 如果大于0,则等待maxWaitMillis长时间,如果没有空闲对象,将抛出NoSuchElementException异常。
         * 可以根据需要自己调整,单位是毫秒。
         * 默认值是5000L
         */
        private long maxWaitMillis = DEFAULT_MAX_WAIT_MILLIS;
        /**
         * 对象最小的空闲时间。如果为小于等于0,最Long的最大值,如果大于0,当空闲的时间大于这个值时,执行移除这个对象操作。
         * 可以避免连接泄漏
         * 默认值是-1
         */
        private long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
        /**
         * shutdown驱逐线程的超时时间。当创建驱逐线(evictor)程时,如发现已有一个evictor正在运行则会停止该evictor,
         * evictorShutdownTimeoutMillis表示当前线程需等待多长时间让ScheduledThreadPoolExecutor停止该evictor线程。
         * (evictor继承自TimerTask,由ScheduledThreadPoolExecutor进行调度)
         * 默认值是10000L,即10秒
         */
        private long evictorShutdownTimeoutMillis = DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
        /**
         * 对象最小的空间时间,如果小于等于0,取Long的最大值,如果大于0,当对象的空闲时间超过这个值,
         * 并且当前空闲对象的数量大于最小空闲数量(minIdle)时,执行移除操作。
         * 这个和上面的minEvictableIdleTimeMillis的区别是,它会保留最小的空闲对象数量。而上面的不会,是强制性移除的。
         * 默认值是1000L * 60L * 30L,即30分钟
         */
        private long softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
        /**
         * 检测空闲对象线程每次检测的空闲对象的数量。如果这个值小于0,则每次检测的空闲对象数量等于当前空闲对象数量除以这个值的绝对值,并对结果向上取整。
         * 默认值是3
         */
        private int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
        /**
         * 在创建对象时检测对象是否有效,true是,默认值是false。做了这个配置会降低性能。
         * 默认值是false
         */
        private boolean testOnCreate = DEFAULT_TEST_ON_CREATE;
        /**
         * 在从对象池获取对象时是否检测对象有效,true是;默认值是false。做了这个配置会降低性能。
         * 默认值是false
         */
        private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
        /**
         * 在向对象池中归还对象时是否检测对象有效,true是,默认值是false。做了这个配置会降低性能。
         * 默认值是false
         */
        private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
        /**
         * 在检测空闲对象线程检测到对象不需要移除时,是否检测对象的有效性。
         * true是,默认值是false。建议配置为true,不影响性能,并且保证安全性。
         * 默认值是true
         */
        private boolean testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
        /**
         * 空闲对象检测线程的执行周期,即多长时间执行一次空闲对象检测。
         * 单位是毫秒数。如果小于等于0,则不执行检测线程。
         * 默认值是1000L * 60L * 10L,即10分钟
         */
        private long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
        /**
         * 当对象池没有空闲对象时,新的获取对象的请求是否阻塞。true阻塞。
         * 默认值是true
         */
        private boolean blockWhenExhausted = DEFAULT_BLOCK_WHEN_EXHAUSTED;
        /**
         * 是否注册JMX
         * 默认值是true
         */
        private boolean jmxEnabled = DEFAULT_JMX_ENABLE;
        /**
         * JMX前缀
         * 默认值是pool
         */
        private String jmxNamePrefix = DEFAULT_JMX_NAME_PREFIX;
        /**
         * 使用jmxNameBase + jmxNamePrefix + i来生成ObjectName
         * 默认值是sftp
         */
        private String jmxNameBase = DEFAULT_JMX_NAME_BASE;



项目信息
路漫漫其修远兮,吾将上下而求索
码云:https://gitee.com/javacoo/sftp-spring-boot-starter
QQ:164863067
作者/微信:javacoo
邮箱:xihuady@126.com
下载地址

https://gitee.com/javacoo/sftp-spring-boot-starter

<think>嗯,用户这次问的是sftp限制连接数的方法。之前系统给的引用资料里提到了sftp命令的基本用法和Linux常用命令,但没直接回答连接数限制问题。用户应该是个Linux系统管理员,想控制sftp服务器的并发访问量。 用户可能遇到了服务器资源被sftp连接占满的情况,需要快速解决方案。深层需求可能是想优化服务器性能或加强安全管控。从ta明确要求"限制连接数"的表述看,应该有基本的Linux知识储备。 这个问题需要分两层解决:服务端限制和客户端限制。服务端更常见,主要靠sshd_config配置: - MaxSessions控制单个IP的总会话数 - MaxStartups限制未认证连接数 - 搭配ChrootDirectory会更安全 引用资料里tar/netstat那些命令虽然相关度不高,但kill命令那段提示我可以补充连接管理技巧。比如用`netstat -ntp | grep ':22'`找异常连接再kill,这种实战技巧用户应该需要。 还得提醒用户注意配置陷阱:Match块要写在文件末尾,改完必须重启sshd。上次看到有人配置了MaxSessions但忘了重启服务,排查半天... </think>在 Linux 中限制 SFTP 连接数主要通过配置 **OpenSSH 服务端**实现(因 SFTP 是 SSH 协议的子系统)。以下是分步操作方法: --- ### 🔧 方法一:修改 `sshd_config` 限制全局连接数 1. **编辑配置文件** ```bash sudo vi /etc/ssh/sshd_config ``` 2. **添加或修改以下参数** ```bash # 限制最大并发会话数(单个IP) MaxSessions 3 # 每个IP最多允许3个SSH会话(含SFTP) MaxStartups 10:30:100 # 控制未完成认证的连接数(默认值) ``` - **`MaxSessions`**:每个客户端 IP 允许的最大并发连接数(包括 SSH 和 SFTP)。 - **`MaxStartups`**:限制未完成认证的连接队列(格式 `start:rate:full`,如 `10:30:100` 表示第 11 个连接按 30% 概率拒绝,直到 100 连接时全部拒绝)[^1][^2]。 3. **重启 SSH 服务生效** ```bash sudo systemctl restart sshd ``` --- ### 🔐 方法二:结合 `Match` 块限制特定用户/组 1. **在 `sshd_config` 末尾添加** ```bash Match Group sftpusers # 针对 sftpusers 用户组 MaxSessions 1 # 该组用户每个IP仅允许1个连接 ForceCommand internal-sftp # 限制仅使用SFTP(禁止Shell) ``` --- ### 📊 查看当前 SFTP 连接数 使用以下命令监控实时连接: ```bash # 查看所有 SFTP 进程 ps -ef | grep "sftp-server" # 统计当前 SFTP 连接数 netstat -ntp | grep ':22' | grep -i "established" | wc -l ``` --- ### ️ 注意事项 1. **连接类型区分** SFTP 与 SSH 共享连接池,`MaxSessions` 同时影响两者。 2. **资源限制** 可配合 `ulimit` 限制用户进程数(如 `ulimit -u 50` 限制最大进程数)。 3. **防火墙辅助** 用 `iptables` 限制 IP 并发连接(例:`iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP`)。 --- ### 📚 相关问题 1. **如何单独限制 SFTP 连接而不影响 SSH?** > 需通过 `Subsystem` 配置独立 SFTP 服务端口(需代码改造),或强制用户组仅用 SFTP(如 `ForceCommand internal-sftp`)[^1]。 2. **超出连接限制时客户端会收到什么错误提示?** > 连接被拒绝或超时(如 `ssh_exchange_identification: Connection closed by remote host`)。 3. **如何针对不同用户设置不同的连接数上限?** > 在 `sshd_config` 中使用多个 `Match User` 或 `Match Group` 块分别定义。 --- > 以上配置基于 OpenSSH 实现,适用于主流 Linux 发行版(Ubuntu/CentOS 等)。修改前请备份配置文件,测试后再重启服务[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

javacoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值