RXAndroid-exception:rx.exceptions.MissingBackpressureException

本文介绍在使用RxAndroid进行长时间数据文件读取时遇到的MissingBackpressureException异常及其解决方法。通过调整数据读取量及使用特定操作符,避免生产者发送速度过快导致的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近刚开始接触RxAndroid,刚刚起步,一切还在学习中。关于RxAndroid的基础知识什么的,大家可以自行度娘,很多人写的都不错,我也就不再赘述了,这篇介绍RxAndroid的入门知识的还不错,大家可以看看。

http://gank.io/post/560e15be2dca930e00da1083#toc_1

这次就来讲讲使用RxAndroid遇到的第一关。。。

rx.exceptions.MissingBackpressureException

这个异常其实网上的解释已经很多了,而且都比我的解决方法好了很多,在此我只根据我的代码来解释这一问题。
首先我的代码:

private void readFileSubsection() {
		mECGFileName = mFileCaseModel.getPath();
		try {
			mFIS_ReadFile = new FileInputStream(mECGFileName);
		} catch (IOException e) {
			e.printStackTrace();
			finishLoad(false);
		}
		Observable.create(new Observable.OnSubscribe<short[]>() {

			@Override
			public void call(Subscriber<? super short[]> arg0) {
				try {
					readDatasSubsection(arg0);
				} catch (IOException e) {
					if (isLoading) {
						arg0.onError(e);
					}
				}
			}
		}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mRXReadSectionSubscriber);
	}

	public void readDatasSubsection(Subscriber<? super short[]> subscriber) throws IOException {
		List<Short> totalDatas = new ArrayList<Short>();
		List<Short> tempDatasList = new ArrayList<Short>();
		byte[] tempdatas = new byte[6];
		int count = 0;
		final Integer beatNum = new Integer(0);
		final Integer ArrhymiaNum = new Integer(0);
		final Integer STNum = new Integer(0);
		while ((count = mFIS_ReadFile.read(tempdatas)) != -1 && isLoading) {
			if (count < 6) {
				// 不够6个字节的,计算字节数对应的数据点数
				count = (int) (count / 1.5);
				for (int i = 0; i < count; i++) {
					totalDatas.add((short) 2048); // 最后几个点全部置为0
				}
				break;
			}
			tempDatasList = DataProgress.toECGWaveDatas(tempdatas);

			for (int i = 0; i < 4; i++) {
				totalDatas.add(tempDatasList.get(i));
			}
			if (totalDatas.size() > 60 * ConstValue.SAMPLE_RATE) {
				short[] data = MathUtil.convList2Arr(totalDatas);
				RTECG.filter(data, data.length);
				subscriber.onNext(data);
				totalDatas.clear();
			}
			tempDatasList.clear();
			tempdatas = new byte[6];
		}
		if (totalDatas.size() > 0 && isLoading) { // 读取到的数据不够60s
			short[] data = MathUtil.convList2Arr(totalDatas);
			RTECG.filter(data, data.length);
			subscriber.onNext(data);
			totalDatas.clear();
			subscriber.onCompleted();
		}
		mFIS_ReadFile.close();
	}

.....

代码的运用场景是,读取一个很长时间的数据文件,然后绘制波形。所以开始使用RxAndroid异步处理的时候,设计每次读取60s的数据然后更新波形数据,然后。。然后就出现了这个异常。。

rx.exceptions.MissingBackpressureException

通过搜索该异常的解决方案,得知是因为生产者(读文件)发送的太快了,而消费者(更新波形数据)消费的太慢,导致该异常的出现。
得知了该异常出现的原因,那么就修改了。反正我是分段读取文件的,读取60s的数据太快了,那就把读取数据的时间增加就可以了,后来我就把读取数据的大小改为读取30min的数据再发送,这样就解决了该问题。

// 增加每次循环读取到的数据长度为30min
totalDatas.size() > 1800 * ConstValue.SAMPLE_RATE

后来看到有介绍RxAndroid各种操作符的,才知道起始可以用到其他的操作符来解决该问题,我大概看了下,发现那些操作符大都是通过增加缓存或者丢弃数据来实现的,感觉不太适合我(个人理解…),不过可能是运用场景的问题,那些操作符还是很有用的,有兴趣的可以看看,这个写的还不错。

http://blog.chengyunfeng.com/?p=981&utm_source=tuicool&utm_medium=referral

<think>我们之前已经讨论过Hikari连接池初始化失败的问题,现在用户再次遇到同样的错误日志。我们需要确保回答的全面性和针对性,同时注意避免重复之前的内容,但可以补充新的角度。 错误信息:HikariPool-1 - Exception during pool initialization 和 Communications link failure 常见原因: 1. 数据库服务不可达(网络问题、数据库未启动) 2. 连接配置错误(错误的URL、端口、数据库名、用户名密码) 3. 数据库资源不足(连接数满、内存不足) 4. 防火墙或安全组限制 5. 数据库驱动问题或版本不兼容 由于之前已经详细讨论过解决方案,这里可以补充一些新的排查点和注意事项,特别是针对Docker环境。 回答结构: 1. 快速诊断步骤(针对Docker环境) 2. 配置检查要点 3. 高级网络问题排查 4. 数据库连接池优化建议 5. 预防措施 注意:最后必须提出3-5个相关问题。</think>### Hikari连接池初始化失败深度排查与解决 #### 关键错误分析 ``` HikariPool-1 - Exception during pool initialization com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure ``` 此错误表明应用无法建立数据库连接,核心原因包括: 1. **网络连通性问题**(最常见): - 容器间网络隔离或DNS解析失败 - 防火墙/安全组阻止3306端口通信 ```bash # 在应用容器内测试连通性 telnet mysql_host 3306 nc -zv mysql_host 3306 ``` 2. **MySQL服务状态异常**: - MySQL容器崩溃或未启动 - 资源不足导致服务停止 ```bash # 检查MySQL容器状态 docker logs mysql_container docker exec mysql_container mysqladmin status ``` 3. **认证配置错误**: - 用户名/密码不正确 - 用户权限不足或主机限制 ```sql -- 验证用户权限 SHOW GRANTS FOR 'app_user'@'%'; ``` 4. **连接参数问题**: - JDBC URL格式错误 - 时区或SSL配置不匹配 ```properties # 正确URL格式 jdbc:mysql://mysql:3306/dbname?useSSL=false&serverTimezone=Asia/Shanghai ``` #### 分步解决方案 **步骤1:网络诊断与修复** ```bash # 1. 检查容器网络 docker network inspect bridge # 2. 验证DNS解析 docker exec iot-backend nslookup mysql_host # 3. 创建专用网络 docker network create iot-network docker network connect iot-network iot-backend docker network connect iot-network mysql_container ``` **步骤2:MySQL服务验证** ```bash # 1. 检查服务状态 docker ps -f name=mysql_container # 2. 进入MySQL检查 docker exec -it mysql_container mysql -u root -p > SHOW VARIABLES LIKE 'max_connections'; > SHOW PROCESSLIST; # 3. 重启服务 docker restart mysql_container ``` **步骤3:连接配置修复** ```yaml # application.yml 正确配置 spring: datasource: url: jdbc:mysql://mysql:3306/iot_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai username: iot_user password: secure_pass driver-class-name: com.mysql.cj.jdbc.Driver hikari: connection-timeout: 30000 initialization-fail-timeout: -1 # 无限重试 ``` **步骤4:连接池调试** ```java // 启用详细日志 @Bean public HikariDataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(env.getProperty("spring.datasource.url")); config.setUsername(env.getProperty("spring.datasource.username")); config.setPassword(env.getProperty("spring.datasource.password")); config.addDataSourceProperty("logger", "com.mysql.cj.log.Slf4JLogger"); config.addDataSourceProperty("profileSQL", "true"); return new HikariDataSource(config); } ``` #### Docker环境特殊问题处理 **问题1:容器间名称解析失败** ```yaml # docker-compose.yml 解决方案 services: iot-backend: links: - mysql:mysql # 显式链接 networks: - iot-network mysql: hostname: mysql-db # 固定主机名 networks: - iot-network networks: iot-network: driver: bridge ``` **问题2:瞬时连接失败** ```bash # 启动脚本添加健康检查 #!/bin/bash until nc -z mysql 3306; do echo "等待MySQL启动..." sleep 2 done java -jar app.jar ``` **问题3:权限配置错误** ```sql -- 创建专用用户 CREATE USER 'iot_user'@'%' IDENTIFIED BY 'secure_pass'; GRANT ALL PRIVILEGES ON iot_db.* TO 'iot_user'@'%'; FLUSH PRIVILEGES; ``` #### 预防措施 1. **启动顺序控制**: ```yaml # docker-compose.yml services: iot-backend: depends_on: mysql: condition: service_healthy mysql: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 3s retries: 10 ``` 2. **连接池监控**: ```yaml # Spring Boot Actuator配置 management: endpoints: web: exposure: include: hikari,health ``` 3. **自动重连机制**: ```properties # JDBC连接参数 spring.datasource.hikari.connection-init-sql=SELECT 1 spring.datasource.hikari.keepaliveTime=30000 spring.datasource.hikari.maxLifetime=1800000 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值