生产者创建消息。在其他基于发布与订阅的消息系统中,生产者可能被称为发布者 或 写入者。
一般情况下,一个消息会被发布到一个特定的主题上。生产者在默认情况下把消息均衡地分布到主题的所有分区上,而并不关心特定消息会被写到哪个分区。不过,在某些情况下,生产者会把消息直接写到指定的分区。这通常是通过消息键和分区器来实现的,分区器为键生成一个散列值,并将其映射到指定的分区上。这样可以保证包含同一个键的消息会被写到同一个分区上。生产者也可以使用自定义的分区器,根据不同的业务规则将消息映射到分区。
生产者发送消息主要有 2 种方式:同步发送消息、异步发送消息
同步发送消息:我们调用 KafkaProducer 的 send() 方法发送消息,send() 方法会返回一个包含 RecordMetadata 的 Future 对象,然后调用 Future 的 get() 方法等待 Kafka 响应,通过 Kafka 的响应,我们就可以知道消息是否发送成功。
我们调用 KafkaProducer 的 send() 方法发送 ProducerRecord 对象,消息先是被放进缓冲区,然后使用单独的线程将消息发送到服务器端。
异常处理
如果在发送数据之前或者在发送过程中发生了任何错误,比如 broker 返回了一个不允许重发消息的异常或者已经超过了重发的次数,那么就会抛出异常。在发送消息之前,生产者也是有可能发生异常的。这些异常有可能是 SerializationException(说明序列化消息失败)、BufferExhaustedException 或 TimeoutException(说明缓冲区已满),又或者是 InterruptException(说明发送线程被中断)。
KafkaProducer 一般会发生两类错误。
public void send(String topic, String key, String val) {
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(topic, key, val);
try {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(producerRecord);
SendResult<String, String> sendResult = future.get();
} catch (Exception e) {
e.printStackTrace();
}
}
异步发送消息:我们调用 KafkaProducer 的 send() 方法,并指定一个回调方法,在服务器返回响应时调用该方法。
大多数时候,我们并不需要等待响应。不过在遇到消息发送失败时,我们需要抛出异常、记录错误日志,或者把消息写入“错误消息”文件以便日后分析。为了在异步发送消息的同时能够对异常情况进行处理,生产者提供了回调支持。
为了使用回调,需要一个实现了 org.apache.kafka.clients.producer.Callback 接口的类,这个接口只有一个 onCompletion() 方法。如果 Kafka 返回一个错误,onCompletion() 方法会抛出一个非空异常。通过 onCompletion() 方法抛出的异常,我们可以对发送失败的消息进行处理。一般情况下,因为生产者会自动进行重试,所以就没必要在代码逻辑里处理那些可重试的错误。你只需要处理那些不可重试的错误或重试次数超出上限的情况。
private class DemoProducerCallback implements Callback {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e != null) {
e.printStackTrace();
}
}
}
ProducerRecord<String, String> record = new ProducerRecord<>("CustomerCountry", "Biomedical Materials", "USA");
producer.send(record, new DemoProducerCallback());
ProducerRecord 对象包含目标主题、消息键和值(消息)。
这里的关键之处在于,同一个键总是被映射到同一个分区上,所以在进行映射时,我们会使用主题的所有分区,而不仅仅是可用的分区。这也意味着,如果写入数据的分区是不可用的,那么就会发生错误。
只有在不改变主题分区数量的情况下,键与分区之间的映射才能保持不变。一旦主题增加了新的分区,那么键与分区之间的映射关系就改变了。如果要使用键来映射分区,那么最好在创建主题的时候就把分区规划好,而且永远不要增加新分区。
生产者可以使用自定义的分区器,根据不同的业务规则将消息映射到分区。
通过分区器实现自定义分区策略的步骤:
public class MyPartitioner implements Partitioner {
/**
* 返回信息对应的分区
*
* @param topic 主题
* @param key 消息的 key
* @param keyBytes 消息的 key 序列化后的字节数组
* @param value 消息的 value
* @param valueBytes 消息的 value 序列化后的字节数组
* @param cluster 集群元数据可以查看分区信息
* @return
*/
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
if ((keyBytes == null) || (!(key instanceof String))) {
throw new InvalidRecordException("We expect all messages to have String type as key");
}
// 实现自己的分区策略
// 返回数据写入的分区号
return 0;
}
// 关闭资源
@Override
public void close() {
}
// 配置方法
@Override
public void configure(Map<String, ?> configs) {
}
}
《Kafka 权威指南》第 3 章:Kafka 生产者——向 Kafka 写入数据
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
假设我有200个昂贵的方法调用(每个都有不同的参数)。出于某种原因,我可以并行执行其中的5个调用,但不能更多。我可以一次执行一个,但一次执行5个要快5倍。我想一直执行五件事。不想排五个,等五个都排完了,再排五个。如果我排队A、B、C、D、E并且C先完成,我想立即用F替换它,即使A和B还没有完成。我一直在研究这个问题,因为我可以想象它会定期发生。解决方案似乎是生产者-消费者模式,Ruby在其标准库中内置了一些用于该模式的结构(Queue和SizedQueue)。我玩过代码示例,阅读了一些文档,我想我对它有一个粗略的了解。但是我有一些问题我对我的解决方案没有信心,而且多线程的整个领域对我来
我有带有gemwebsocket-rails0.7的Rails3.2应用程序。在开发机上,一切正常在生产环境中,我使用Nginx/1.6作为代理服务器,Unicorn作为http服务器。Thin用于独立模式(在https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode之后)。nginx配置:location/websocket{proxy_passhttp://localhost:3001/websocket;proxy_http_version1.1;proxy_set_headerUp
有时您会制作特定于项目的gem。这有助于将一些“责任”从主Rails应用程序中抽象出来并转移到一个更加模块化的地方。gem将位于您应用程序的此处:gem'example_gem',path:'./example_gem'你捆绑,一切都很好。现在,您gitinitgem并将其存储在github上它自己的repo中。您尝试这样做以使其对开发人员友好:group:development,:testdogem'example_gem',path:'./example_gem'endgroup:productiondogem'example_gem',github:'company/exampl
我正在将我的第一个Rails应用程序放到互联网上,我已经阅读了有关安全性的Rails指南并实现了其中列出的要点,但有兴趣了解其他信息吗?另外,我目前将上传的内容存储在公共(public)/文档中,这样可以吗?我注意到没有保护目录的htaccess文件。 最佳答案 如果您想保密,将上传的内容存储在可预测的位置是个坏主意。如果您不关心访问它的人,那也没关系。使用.htaccess密码保护目录是一个很好的解决方案。您应该使用Acunetx测试您的应用程序是否存在漏洞($$)或Wapiti(开源)。您还应该阅读:Whatshouldadev
(免责声明:在Heroku上部署Sinatra的新手。)我看过http://www.sinatrarb.com/configuration.html它告诉我set:environment,:production。我的问题是,我该如何指定它:“在Heroku中,将环境设置为生产环境,否则留在测试/开发中。”此外,即使在set:environment,:production这行之后,我也不认为它在工作,因为当我尝试在本地rackup应用程序时,它是仍在运行(当我知道(或者我认为我知道)它不应该因为我没有在我的计算机上安装postgres时)。gem文件group:productiondog
我想将我的基础架构迁移到jRuby。我看到的最完整的选项是torquebox。任何人都可以分享一些关于它的东西吗?与tomcat/jetty相比? 最佳答案 我正在使用TorqueBox1.0ReleaseCandidate作为24x7关键任务生产解决方案。它已被用作我项目中所有新开发的首选平台,取代了非常昂贵的商业ESB。虽然HornetQ还没有(还)取代我们企业的企业JMS提供者,但我们正在大量使用HornetQ来处理越来越多的松散耦合的JRuby组件。在我看来,TorqueBox是具有内置高可用性功能的世界级应用服务器、高性能
我正在尝试将数据从我的生产数据库传输到我的登台数据库,但没有成功。我正在关注heroku的相关文档:http://devcenter.heroku.com/articles/pgbackups#transfers这些是我运行的命令...$herokuaddons:addpgbackups--remotestaging$herokuaddons:addpgbackups--remoteproduction$herokupgbackups:capture--remoteproduction$herokupgbackups:restoreDATABASE`herokupgbackups:ur
我正在尝试弄清楚如何在生产环境中部署我的ruby-on-rails应用程序。操作系统是ubuntu,应用程序使用Postgres。我已经设法部署了应用程序并能够登录等...但是某些功能无法正常工作(我是应用程序和Rails的新手)。该应用程序使用Elasticsearch,我已经安装了它并且服务正在运行(我可以通过http://localhost:9200访问该页面)。但是,当应用程序尝试访问Elasticsearch的组件时,出现错误。/app/lib/tasks目录下有一个rake文件,里面有几个文件,其中一个是elasticsearch.rakenamespace:appdo