public void Start(ProducerAkkaOption producerAkkaOption) { materializer_producer = producerSystem.Materializer(); var producer = ProducerSettings <Null, string> .Create(producerSystem, null, null) .WithBootstrapServers(producerAkkaOption.BootstrapServers); producerList[producerAkkaOption.ProducerName] = producer; }
public ProducerActor(ProducerAkkaOption producerAkkaOption) { //Actor Init sentMessageCount = 0; if (producerAkkaOption.SecurityOption != null) { producerConfig = new ProducerConfig() { BootstrapServers = producerAkkaOption.BootstrapServers, SecurityProtocol = producerAkkaOption.SecurityOption.SecurityProtocol, SaslMechanism = producerAkkaOption.SecurityOption.SaslMechanism, SaslUsername = producerAkkaOption.SecurityOption.SaslUsername, SaslPassword = producerAkkaOption.SecurityOption.SaslPassword, SslCaLocation = producerAkkaOption.SecurityOption.SslCaLocation, //Debug = "security,broker,protocol" //Uncomment for librdkafka debugging information }; } else { producerConfig = new ProducerConfig() { BootstrapServers = producerAkkaOption.BootstrapServers //Debug = "security,broker,protocol" //Uncomment for librdkafka debugging information }; } producer = new ProducerBuilder <long, string>(producerConfig).SetKeySerializer(Serializers.Int64).SetValueSerializer(Serializers.Utf8).Build(); //Actor Message : 아래코드는 생성시, 메시지에따른 이벤트 처리기를 셋팅합니다. // 속도조절기로부터 OutPut된 이벤트가 이곳으로 인입 // 메시지에 따른 분기조건이 많아질시, if,switch 조합보다 패턴매칭 활용 추천 : https://docs.microsoft.com/ko-kr/dotnet/csharp/tutorials/pattern-matching ReceiveAsync <BatchData>(async msg => { if (msg.Data is KafkaTextMessage) { sentMessageCount++; var kafkaMsg = msg.Data as KafkaTextMessage; var deliveryReport = await producer.ProduceAsync(kafkaMsg.Topic, new Message <long, string> { Key = DateTime.UtcNow.Ticks, Value = kafkaMsg.Message }); logger.Info(string.Format("Message {0} sent (value: '{1}')", sentMessageCount, kafkaMsg.Message)); } }); }
static public void StartKafkaTest(IApplicationBuilder app, ActorSystem actorSystem) { // 기호에따라 사용방식이 약간 다른 KAFKA를 선택할수 있습니다. //################################################################## //##### Confluent.Kafka를 Akka액터 모드로 연결한 모드로 //##### 보안연결이 지원하기때문에 Saas형태의 Kafka에 보안연결이 가능합니다. //##### 커스텀한 액터를 생성하여,AkkaStream을 이해하고 직접 연결할수 있을때 유용합니다. //################################################################## //ProducerActor var producerAkkaOption = new ProducerAkkaOption() { BootstrapServers = "webnori.servicebus.windows.net:9093", ProducerName = "webnori-kafka", SecurityOption = new KafkaSecurityOption() { SecurityProtocol = SecurityProtocol.SaslSsl, SaslMechanism = SaslMechanism.Plain, SaslUsername = "******", SaslPassword = "******", SslCaLocation = "./cacert.pem" } }; string producerActorName = "producerActor"; var producerActor = AkkaLoad.RegisterActor(producerActorName /*AkkaLoad가 인식하는 유니크명*/, actorSystem.ActorOf(Props.Create(() => new ProducerActor(producerAkkaOption)), producerActorName /*AKKA가 인식하는 Path명*/ )); producerActor.Tell(new BatchData() { Data = new KafkaTextMessage() { Topic = "akka100", Message = "testData" } }); //ConsumerActor var consumerAkkaOption = new ConsumerAkkaOption() { BootstrapServers = "webnori.servicebus.windows.net:9093", Topics = "akka100", AutoOffsetReset = AutoOffsetReset.Earliest, KafkaGroupId = "akakTestGroup", RelayActor = null, //작업자 액터를 연결하면, 소비메시지가 작업자에게 전달된다 ( 컨슘기능과 작업자 기능의 분리) SecurityOption = new KafkaSecurityOption() { SecurityProtocol = SecurityProtocol.SaslSsl, SaslMechanism = SaslMechanism.Plain, SaslUsername = "******", SaslPassword = "******", SslCaLocation = "./cacert.pem" } }; string consumerActorName = "consumerActor"; var consumerActor = AkkaLoad.RegisterActor(consumerActorName /*AkkaLoad가 인식하는 유니크명*/, actorSystem.ActorOf(Props.Create(() => new ConsumerActor(consumerAkkaOption)), consumerActorName /*AKKA가 인식하는 Path명*/ )); //컨슈머를 작동시킨다. consumerActor.Tell(new ConsumerStart()); //################################################################## //##### Akka.Streams.Kafka(의존:Confluent.Kafka) 을 사용하는 모드로, Security(SSL)이 아직 지원되지 않습니다. //##### Private으로 구성된, Kafka Pass 모드일때 사용가능합니다. //##### AkkaStream.Kafka가 제공하는 스트림을 활용핼때 장점이 있습니다. //################################################################## // KAFKA - // 각 System은 싱글톤이기때문에 DI를 통해 Controller에서 참조획득가능 var consumerSystem = app.ApplicationServices.GetService <ConsumerSystem>(); var producerSystem = app.ApplicationServices.GetService <ProducerSystem>(); //소비자 : 복수개의 소비자 생성가능 consumerSystem.Start(new ConsumerAkkaOption() { KafkaGroupId = "testGroup", BootstrapServers = "kafka:9092", RelayActor = null, //소비되는 메시지가 지정 액터로 전달되기때문에,처리기는 액터로 구현 Topics = "akka100", }); //생산자 : 복수개의 생산자 생성가능 producerSystem.Start(new ProducerAkkaOption() { BootstrapServers = "kafka:9092", ProducerName = "producer1", }); List <string> messages = new List <string>(); for (int i = 0; i < 10; i++) { messages.Add($"message-{i}"); } //보너스 : 생산의 속도를 조절할수 있습니다. int tps = 10; producerSystem.SinkMessage("producer1", "akka100", messages, tps); }