- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
今天好哥们找我借钱 哥们:兄弟,我最近手头紧,能不能借我点... 我:我手头也不宽裕,要不你试试银行贷款或者花呗? 哥们:不行,那个借了要还的 我:... 。
某天下午,生产监控告警:消息积压,队列 xxx 消息数超过 100;我第一时间想到的是应用服务是不是停了,但应用服务存活监控又没有告警,但我还是找值班运维同事帮忙确认了下,确认结果是服务的 6 个节点都是存活的,然后我又让运维确认了下队列的消费者情况,结果发现消费者列表中只有 2 个节点的消费者,其他 4 个节点的消费者不见了,所以消息消费不过来,导致了消息积压! 。
所以问题来了 。
那 4 个节点的注册的消费者为何消失?
但当务之急是解决消息积压的问题,所以让运维重启那 4 个节点的服务,消费者重新注册上,消息得以快速消费,消息积压告警得以恢复 。
生产问题虽暂时得以解决,但未找到根因,还是存在复发风险;下面就请大家跟随我的脚本,来看看我是如何排查的 。
直接查 ERROR 级别的日志,很容易就能就找到了关键日志 。
Consumer thread error, thread abort. 。
以及异常堆栈 。
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:300)
at java.lang.StringCoding.encode(StringCoding.java:344)
at java.lang.String.getBytes(String.java:918)
...
Consumer thread error, thread abort 大家能看懂吧,就是字面意思 。
消费者线程错误,线程中止 。
消费者线程就是我们前面提到的队列消费者,一个队列消费者就是一个消费者线程,消费者线程中止那就意味着队列消费者中止,也就对应文章标题中的 消费者消失;是不是离真相越来越近了?
OutOfMemoryError 是不是很熟悉,内存溢出嘛 。
OutOfMemoryError 表示 Java 虚拟机在堆内存中没有足够的空间来分配对象 。
问你们一个问题:OOM 一定会导致 JVM 退出吗,这个问题你们先思考,后面答案会揭晓 。
回到正题,从关键日志以及异常堆栈,我们是不是可以得出以下推测 。
OOM 会导致消费者线程中止 。
有了推测,那就去验证呗;我先给大家模拟下案例,基于 SpringBoot,pom.xml 关键依赖 。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
配置文件 application.yml 。
server:
port: 8088
spring:
rabbitmq:
host: 192.168.2.118
port: 5672
username: admin
password: admin
virtual-host: /
listener:
simple:
acknowledge-mode: manual #设置确认模式手工确认
concurrency: 3 #消费者个数,线程个数
prefetch: 1
RabbitMQ 配置 TaskRabbitConfig.java 。
package com.qsl.rabbit.config;
import com.qsl.rabbit.constant.Constant;
import com.qsl.rabbit.listener.TaskMessageListener;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: 青石路
*/
@Configuration
public class TaskRabbitConfig {
@Value("${spring.rabbitmq.listener.simple.concurrency:3}")
private int concurrency;
@Value("${spring.rabbitmq.listener.simple.prefetch:1}")
private int prefetch;
@Bean
public DirectExchange taskExchange() {
return new DirectExchange(Constant.TASK_EXCHANGE, true, false);
}
@Bean
public Queue taskQueue() {
return new Queue(Constant.TASK_QUEUE, true, false, false);
}
@Bean
public Binding bindingTaskQueue() {
return BindingBuilder.bind(taskQueue()).to(taskExchange()).with(Constant.TASK_QUEUE);
}
@Bean
public SimpleMessageListenerContainer taskMessageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//设置确认模式手工确认
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
container.setQueueNames(Constant.TASK_QUEUE);
//消费者个数,线程个数
container.setConcurrentConsumers(concurrency);
//设置预处理个数
container.setPrefetchCount(prefetch);
container.setMessageListener(new TaskMessageListener());
return container;
}
}
消息监听器 TaskMessageListener.java 。
/**
* @author: 青石路
*/
@Slf4j
public class TaskMessageListener implements ChannelAwareMessageListener {
@Override
public void onMessage(Message message, Channel channel) {
String content = new String(message.getBody(), StandardCharsets.UTF_8);
log.info("消费者接收到消息:{}", content);
handleTask(content);
try {
// 手动ACK
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException e) {
log.error("消息确认失败,异常:", e);
}
}
private void handleTask(String message) {
try {
// 业务处理
log.info("处理任务:{}", message);
log.info("任务处理完成");
} catch (Exception e) {
log.error("处理任务失败,异常:", e);
}
}
}
业务处理的时候进行 Exception 捕获,并且手动确认消息,我相信你们平时都是这么用的,这难道有什么问题?我调整下 handleTask 方法 。
/**
* 业务处理
* @param message 消息内容
* @author: 青石路
*/
private void handleTask(String message) {
try {
// 业务处理
log.info("处理任务:{}", message);
int i = 3 / (message.length() % 10);
if (i == 1) {
throw new OutOfMemoryError("模拟内存溢出");
}
log.info("任务处理结果:{}", i);
} catch (Exception e) {
log.error("处理任务失败,异常:", e);
}
}
启动服务后,队列消费者情况如下 。
发送消息 a,日志输出如下 。
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:a
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:a
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|42|任务处理结果:3
相当于业务正常处理;我们再发送消息 abcdefghij,日志输出如下 。
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:abcdefghij
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:abcdefghij
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|ERROR|44|处理任务失败,异常:
java.lang.ArithmeticException: / by zero
at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:38)
at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
at java.lang.Thread.run(Thread.java:748)
被除数为 0,出现 ArithmeticException 。
相当于业务处理出现了 Exception,而我们进行了 catch,所以日志打印也符合我们的代码逻辑,也不会对消费者线程造成影响,队列消费者还是最初的那 3 个 。
我们发送消息 ab,日志输出如下 。
2024-09-22 20:36:31|taskMessageListenerContainer-1|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-1|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-2|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-3|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1415|Stopping container from aborted consumer
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|INFO|646|Waiting for workers to finish.
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|INFO|649|Successfully waited for workers to finish.
可以看到,除了我们的业务日志,还有 spring 的日志;从日志可以看出,消息一共被消费了 3 次,但无一例外,都消费失败了,每次失败日志都包括 。
Consumer thread error, thread abort. 。
Stopping container from aborted consumer 。
我们再去看下队列消费者情况 。
我们把这个流程捋一捋 。
消费者线程 taskMessageListenerContainer-1 收到消息,业务处理的时候 OOM 了,Spring 中止该线程,消息未被手动确认,回到队列等待被消费 消费者线程 taskMessageListenerContainer-2 收到消息,业务处理的时候又 OOM,Spring 中止该线程,消息未被手动确认,回到队列等待被消费 消费者线程 taskMessageListenerContainer-3 收到消息,业务处理的时候扔 OOM,Spring 中止该线程,消息未被手动确认,回到队列等待被消费 。
全部的 3 个消费者线程都被 Spring 中止了,对应的 3 个队列消费者也就都无了,消息最终回到队列,等待下一个就绪的消费者消费 。
我们不是 catch 了 Exception 吗,为什么 OutOfMemoryError 还是向上抛给了 Spring ?
OutOfMemoryError 是 Error,并不是 Exception,所以我们的代码并不会捕获 OutOfMemoryError,继续往上抛给了 Spring,而 。
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.AsyncMessageProcessingConsumer#run
中有这么一段代码 。
publishConsumerFailedEvent 发布一个消费者失败事件,事件处理器收到该事件后会中止该线程;这里就不展开讲了,后续我再写一篇源码,给你们好好介绍下 Spring 的中止逻辑 。
至此,OutOfMemoryError 会导致消费者线程中止,大家都清楚了吧;细心的小伙伴可能会有这样的疑问了 。
照理来说,生产中 6 个节点的消费者线程不应该都被中止吗,为什么还剩 2 个节点的消费者?
这 2 个节点内存比较充足,所以 JVM 的堆内存配置的比较大,它们的消费者线程在处理消息的时候,并不会 OOM;而当天正好是业务人员在进行历史大数据量处理,几轮操作下来,把那 4 个内存比较小的节点的消费者全干没了,只剩下那 2 个内存比较大的节点的消费者了 。
根因其实是 OutOfMemoryError,当前只知道是 。
com.fasterxml.jackson.databind.ObjectMapper#writeValueAsString
这个方法导致的,具体原因还待进一步排查 。
因为 OutOfMemoryError 的原因没找到,并且是在操作历史大数据量这种很少出现的场景中触发 OutOfMemoryError,也没有导致服务重启,所以暂定方式是将 ERROR 也捕获 。
/**
* 业务处理
* @param message 消息内容
* @author: 青石路
*/
private void handleTask(String message) {
try {
// 业务处理
log.info("处理任务:{}", message);
int i = 3 / (message.length() % 10);
if (i == 1) {
throw new OutOfMemoryError("模拟内存溢出");
}
log.info("任务处理结果:{}", i);
} catch (Exception | Error e) {
log.error("处理任务失败,异常:", e);
}
}
重新启动服务,继续消费队列中那条未被消费的消息 ab,此时日志输出如下 。
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|ERROR|44|处理任务失败,异常:
java.lang.OutOfMemoryError: 模拟内存溢出
at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
at java.lang.Thread.run(Thread.java:748)
2024-09-22 21:38:57|main|com.qsl.rabbit.RabbitmqApplication|INFO|61|Started RabbitmqApplication in 1.045 seconds (JVM running for 1.515)
虽然业务处理仍然失败,但只有符合我们代码逻辑的错误日志输出,并没有 Spring 的错误日志,此时队列消费者情况如下 。
当然,这只是缓兵之计,最终解决方案还是要分析 OOM 的原因,然后对症下药 。
示例代码:spring-boot-rabbitmq 。
OOM 不一定会导致 JVM 退出,但是 SimpleMessageListenerContainer 会捕获它,然后中止当前线程,对应的队列消费者也就无了 。
业务代码 catch Error 虽说只是缓兵之计,但从健壮性考虑的话,也是一个不错的解决办法 。
但 OOM 的原因还得继续排查,然后对症下药,这才是最终解决之道 。
最后此篇关于记一次RabbitMQ消费者莫名消失问题的排查的文章就讲到这里了,如果你想了解更多关于记一次RabbitMQ消费者莫名消失问题的排查的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
关闭。这个问题是off-topic .它目前不接受答案。 想要改进这个问题? Update the question所以它是on-topic用于堆栈溢出。 关闭 12 年前。 Improve thi
我有一个动态网格,其中的数据功能需要正常工作,这样我才能逐步复制网格中的数据。假设在第 5 行中,我输入 10,则从第 6 行开始的后续行应从 11 开始读取,依此类推。 如果我转到空白的第一行并输入
我有一个关于我的按钮消失的问题 我已经把一个图像作为我的按钮 用这个函数动画 function example_animate(px) { $('#cont
我有一个具有 Facebook 连接和经典用户名/密码登录的网站。目前,如果用户单击 facebook_connect 按钮,系统即可运行。但是,我想将现有帐户链接到 facebook,因为用户可以选
我有一个正在为 iOS 开发的应用程序,该应用程序执行以下操作 加载和设置注释并启动核心定位和缩放到位置。 map 上有很多注释,从数据加载不会花很长时间,但将它们实际渲染到 map 上需要一段时间。
我被推荐使用 Heroku for Ruby on Rails 托管,到目前为止,我认为我真的会喜欢它。只是想知道是否有人可以帮助我找出问题所在。 我按照那里的说明在该网站上创建应用程序,创建并提交
我看过很多关于 SSL 错误的帖子和信息,我自己也偶然发现了一个。 我正在尝试使用 GlobalSign CA BE 证书通过 Android WebView 访问网页,但出现了不可信错误。 对于大多
我想开始使用 OpenGL 3+ 和 4,但我在使用 Glew 时遇到了问题。我试图将 glew32.lib 包含在附加依赖项中,并且我已将库和 .dll 移动到主文件夹中,因此不应该有任何路径问题。
我已经盯着这两个下载页面的源代码看了一段时间,但我似乎找不到问题。 我有两个下载页面,一个 javascript 可以工作,一个没有。 工作:http://justupload.it/v/lfd7不是
我一直在使用 jQuery,只是尝试在单击链接时替换文本字段以及隐藏/显示内容项。它似乎在 IE 中工作得很好,但我似乎无法让它在 FF 中工作。 我的 jQuery: $(function() {
我正在尝试为 NDK 编译套接字库,但出现以下两个错误: error: 'close' was not declared in this scope 和 error: 'min' is not a m
我正在使用 Selenium 浏览器自动化框架测试网站。在测试过程中,我切换到特定的框架,我们将其称为“frame_1”。后来,我在 Select 类中使用了 deselectAll() 方法。不久之
我正在尝试通过 Python 创建到 Heroku PostgreSQL 数据库的连接。我将 Windows10 与 Python 3.6.8 和 PostgreSQL 9.6 一起使用。 我从“ht
我有一个包含 2 列的数据框,我想根据两列之间的比较创建第三列。 所以逻辑是:第 1 列 val = 3,第 2 列 val = 4,因此新列值什么都没有 第 1 列 val = 3,第 2 列 va
我想知道如何调试 iphone 5 中的 css 问题。 我尝试使用 firelite 插件。但是从纵向旋转到横向时,火石占据了整个屏幕。 有没有其他方法可以调试 iphone 5 中的 css 问题
所以我有点难以理解为什么这不起作用。我正在尝试替换我正在处理的示例站点上的类别复选框。我试图让它做以下事情:未选中时以一种方式出现,悬停时以另一种方式出现(选中或未选中)选中时以第三种方式出现(而不是
Javascript CSS 问题: 我正在使用一个文本框来写入一个 div。我使用以下 javascript 获取文本框来执行此操作: function process_input(){
你好,我很难理解 P、NP 和多项式时间缩减的主题。我试过在网上搜索它并问过我的一些 friend ,但我没有得到任何好的答案。 我想问一个关于这个话题的一般性问题: 设 A,B 为 P 中的语言(或
你好,我一直在研究 https://leetcode.com/problems/2-keys-keyboard/并想到了这个动态规划问题。 您从空白页上的“A”开始,完成后得到一个数字 n,页面上应该
我正在使用 Cocoapods 和 KIF 在 Xcode 服务器上运行持续集成。我已经成功地为一个项目设置了它来报告每次提交。我现在正在使用第二个项目并收到错误: Bot Issue: warnin
我是一名优秀的程序员,十分优秀!