winlin

add load balance round robin for brokers.

@@ -152,7 +152,7 @@ ModuleLibIncs=(${SRS_OBJS_DIR}) @@ -152,7 +152,7 @@ ModuleLibIncs=(${SRS_OBJS_DIR})
152 MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer" 152 MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer"
153 "srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_file" 153 "srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_file"
154 "srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts" 154 "srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
155 - "srs_kernel_stream") 155 + "srs_kernel_stream" "srs_kernel_balance")
156 KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh 156 KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
157 KERNEL_OBJS="${MODULE_OBJS[@]}" 157 KERNEL_OBJS="${MODULE_OBJS[@]}"
158 # 158 #
@@ -23,6 +23,8 @@ file @@ -23,6 +23,8 @@ file
23 kernel readonly separator, 23 kernel readonly separator,
24 ../../src/kernel/srs_kernel_aac.hpp, 24 ../../src/kernel/srs_kernel_aac.hpp,
25 ../../src/kernel/srs_kernel_aac.cpp, 25 ../../src/kernel/srs_kernel_aac.cpp,
  26 + ../../src/kernel/srs_kernel_balance.hpp,
  27 + ../../src/kernel/srs_kernel_balance.cpp,
26 ../../src/kernel/srs_kernel_stream.hpp, 28 ../../src/kernel/srs_kernel_stream.hpp,
27 ../../src/kernel/srs_kernel_stream.cpp, 29 ../../src/kernel/srs_kernel_stream.cpp,
28 ../../src/kernel/srs_kernel_codec.hpp, 30 ../../src/kernel/srs_kernel_codec.hpp,
@@ -113,6 +115,8 @@ file @@ -113,6 +115,8 @@ file
113 ../../src/app/srs_app_http_static.cpp, 115 ../../src/app/srs_app_http_static.cpp,
114 ../../src/app/srs_app_ingest.hpp, 116 ../../src/app/srs_app_ingest.hpp,
115 ../../src/app/srs_app_ingest.cpp, 117 ../../src/app/srs_app_ingest.cpp,
  118 + ../../src/app/srs_app_kafka.hpp,
  119 + ../../src/app/srs_app_kafka.cpp,
116 ../../src/app/srs_app_listener.hpp, 120 ../../src/app/srs_app_listener.hpp,
117 ../../src/app/srs_app_listener.cpp, 121 ../../src/app/srs_app_listener.cpp,
118 ../../src/app/srs_app_log.hpp, 122 ../../src/app/srs_app_log.hpp,
@@ -111,6 +111,7 @@ @@ -111,6 +111,7 @@
111 3CC52DDC1ACE4023006FEB01 /* srs_utest_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD21ACE4023006FEB01 /* srs_utest_protocol.cpp */; }; 111 3CC52DDC1ACE4023006FEB01 /* srs_utest_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD21ACE4023006FEB01 /* srs_utest_protocol.cpp */; };
112 3CC52DDD1ACE4023006FEB01 /* srs_utest_reload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD41ACE4023006FEB01 /* srs_utest_reload.cpp */; }; 112 3CC52DDD1ACE4023006FEB01 /* srs_utest_reload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD41ACE4023006FEB01 /* srs_utest_reload.cpp */; };
113 3CC52DDE1ACE4023006FEB01 /* srs_utest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD61ACE4023006FEB01 /* srs_utest.cpp */; }; 113 3CC52DDE1ACE4023006FEB01 /* srs_utest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DD61ACE4023006FEB01 /* srs_utest.cpp */; };
  114 + 3CD247C31BB3F14100DC1922 /* srs_kernel_balance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CD247C11BB3F14000DC1922 /* srs_kernel_balance.cpp */; };
114 3CD88B3F1ACA9C58000359E0 /* srs_app_async_call.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */; }; 115 3CD88B3F1ACA9C58000359E0 /* srs_app_async_call.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */; };
115 3CE6CD311AE4AFB800706E07 /* srs_main_ingest_hls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CE6CD301AE4AFB800706E07 /* srs_main_ingest_hls.cpp */; }; 116 3CE6CD311AE4AFB800706E07 /* srs_main_ingest_hls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CE6CD301AE4AFB800706E07 /* srs_main_ingest_hls.cpp */; };
116 /* End PBXBuildFile section */ 117 /* End PBXBuildFile section */
@@ -389,6 +390,8 @@ @@ -389,6 +390,8 @@
389 3CC52DD51ACE4023006FEB01 /* srs_utest_reload.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_utest_reload.hpp; path = ../../src/utest/srs_utest_reload.hpp; sourceTree = "<group>"; }; 390 3CC52DD51ACE4023006FEB01 /* srs_utest_reload.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_utest_reload.hpp; path = ../../src/utest/srs_utest_reload.hpp; sourceTree = "<group>"; };
390 3CC52DD61ACE4023006FEB01 /* srs_utest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_utest.cpp; path = ../../src/utest/srs_utest.cpp; sourceTree = "<group>"; }; 391 3CC52DD61ACE4023006FEB01 /* srs_utest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_utest.cpp; path = ../../src/utest/srs_utest.cpp; sourceTree = "<group>"; };
391 3CC52DD71ACE4023006FEB01 /* srs_utest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_utest.hpp; path = ../../src/utest/srs_utest.hpp; sourceTree = "<group>"; }; 392 3CC52DD71ACE4023006FEB01 /* srs_utest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_utest.hpp; path = ../../src/utest/srs_utest.hpp; sourceTree = "<group>"; };
  393 + 3CD247C11BB3F14000DC1922 /* srs_kernel_balance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_balance.cpp; path = ../../../src/kernel/srs_kernel_balance.cpp; sourceTree = "<group>"; };
  394 + 3CD247C21BB3F14000DC1922 /* srs_kernel_balance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_balance.hpp; path = ../../../src/kernel/srs_kernel_balance.hpp; sourceTree = "<group>"; };
392 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_async_call.cpp; path = ../../../src/app/srs_app_async_call.cpp; sourceTree = "<group>"; }; 395 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_async_call.cpp; path = ../../../src/app/srs_app_async_call.cpp; sourceTree = "<group>"; };
393 3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_async_call.hpp; path = ../../../src/app/srs_app_async_call.hpp; sourceTree = "<group>"; }; 396 3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_async_call.hpp; path = ../../../src/app/srs_app_async_call.hpp; sourceTree = "<group>"; };
394 3CE6CD301AE4AFB800706E07 /* srs_main_ingest_hls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_main_ingest_hls.cpp; path = ../../../src/main/srs_main_ingest_hls.cpp; sourceTree = "<group>"; }; 397 3CE6CD301AE4AFB800706E07 /* srs_main_ingest_hls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_main_ingest_hls.cpp; path = ../../../src/main/srs_main_ingest_hls.cpp; sourceTree = "<group>"; };
@@ -486,6 +489,8 @@ @@ -486,6 +489,8 @@
486 children = ( 489 children = (
487 3C1232081AAE814D00CE8F6C /* srs_kernel_aac.cpp */, 490 3C1232081AAE814D00CE8F6C /* srs_kernel_aac.cpp */,
488 3C1232091AAE814D00CE8F6C /* srs_kernel_aac.hpp */, 491 3C1232091AAE814D00CE8F6C /* srs_kernel_aac.hpp */,
  492 + 3CD247C11BB3F14000DC1922 /* srs_kernel_balance.cpp */,
  493 + 3CD247C21BB3F14000DC1922 /* srs_kernel_balance.hpp */,
489 3C12321A1AAE814D00CE8F6C /* srs_kernel_buffer.cpp */, 494 3C12321A1AAE814D00CE8F6C /* srs_kernel_buffer.cpp */,
490 3C12321B1AAE814D00CE8F6C /* srs_kernel_buffer.hpp */, 495 3C12321B1AAE814D00CE8F6C /* srs_kernel_buffer.hpp */,
491 3C12320C1AAE814D00CE8F6C /* srs_kernel_codec.cpp */, 496 3C12320C1AAE814D00CE8F6C /* srs_kernel_codec.cpp */,
@@ -900,6 +905,7 @@ @@ -900,6 +905,7 @@
900 3C26E3C61BB146FF00D0F9DB /* srs_app_kafka.cpp in Sources */, 905 3C26E3C61BB146FF00D0F9DB /* srs_app_kafka.cpp in Sources */,
901 3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */, 906 3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */,
902 3C1232971AAE81D900CE8F6C /* srs_app_dvr.cpp in Sources */, 907 3C1232971AAE81D900CE8F6C /* srs_app_dvr.cpp in Sources */,
  908 + 3CD247C31BB3F14100DC1922 /* srs_kernel_balance.cpp in Sources */,
903 3C1232271AAE814D00CE8F6C /* srs_kernel_log.cpp in Sources */, 909 3C1232271AAE814D00CE8F6C /* srs_kernel_log.cpp in Sources */,
904 3C689F961AB6AAAC00C9CEEE /* event.c in Sources */, 910 3C689F961AB6AAAC00C9CEEE /* event.c in Sources */,
905 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */, 911 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */,
@@ -970,7 +976,7 @@ @@ -970,7 +976,7 @@
970 3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */, 976 3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */,
971 3C068D6D1B10175500AA722C /* srs_protocol_stream.cpp in Sources */, 977 3C068D6D1B10175500AA722C /* srs_protocol_stream.cpp in Sources */,
972 3CB25C2A1BB269FD00C97A63 /* jmp_sp.cpp in Sources */, 978 3CB25C2A1BB269FD00C97A63 /* jmp_sp.cpp in Sources */,
973 - 3C068D6D1B10175500AA722C /* srs_protocol_buffer.cpp in Sources */, 979 + 3C068D6D1B10175500AA722C /* srs_protocol_stream.cpp in Sources */,
974 3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */, 980 3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */,
975 3C1232291AAE814D00CE8F6C /* srs_kernel_buffer.cpp in Sources */, 981 3C1232291AAE814D00CE8F6C /* srs_kernel_buffer.cpp in Sources */,
976 3C663F181AB0155100286D8B /* srs_play.c in Sources */, 982 3C663F181AB0155100286D8B /* srs_play.c in Sources */,
@@ -4290,7 +4290,7 @@ SrsConfDirective* SrsConfig::get_kafka_brokers() @@ -4290,7 +4290,7 @@ SrsConfDirective* SrsConfig::get_kafka_brokers()
4290 return NULL; 4290 return NULL;
4291 } 4291 }
4292 4292
4293 - conf->get("brokers"); 4293 + conf = conf->get("brokers");
4294 if (!conf || conf->args.empty()) { 4294 if (!conf || conf->args.empty()) {
4295 return NULL; 4295 return NULL;
4296 } 4296 }
@@ -23,21 +23,28 @@ @@ -23,21 +23,28 @@
23 23
24 #include <srs_app_kafka.hpp> 24 #include <srs_app_kafka.hpp>
25 25
  26 +#include <vector>
  27 +using namespace std;
  28 +
26 #include <srs_kernel_error.hpp> 29 #include <srs_kernel_error.hpp>
27 #include <srs_kernel_log.hpp> 30 #include <srs_kernel_log.hpp>
28 #include <srs_app_config.hpp> 31 #include <srs_app_config.hpp>
29 #include <srs_app_async_call.hpp> 32 #include <srs_app_async_call.hpp>
30 #include <srs_app_utility.hpp> 33 #include <srs_app_utility.hpp>
  34 +#include <srs_kernel_utility.hpp>
  35 +#include <srs_kernel_balance.hpp>
31 36
32 #ifdef SRS_AUTO_KAFKA 37 #ifdef SRS_AUTO_KAFKA
33 38
34 SrsKafkaProducer::SrsKafkaProducer() 39 SrsKafkaProducer::SrsKafkaProducer()
35 { 40 {
  41 + lb = new SrsLbRoundRobin();
36 worker = new SrsAsyncCallWorker(); 42 worker = new SrsAsyncCallWorker();
37 } 43 }
38 44
39 SrsKafkaProducer::~SrsKafkaProducer() 45 SrsKafkaProducer::~SrsKafkaProducer()
40 { 46 {
  47 + srs_freep(lb);
41 srs_freep(worker); 48 srs_freep(worker);
42 } 49 }
43 50
@@ -46,7 +53,7 @@ int SrsKafkaProducer::initialize() @@ -46,7 +53,7 @@ int SrsKafkaProducer::initialize()
46 int ret = ERROR_SUCCESS; 53 int ret = ERROR_SUCCESS;
47 54
48 // when kafka enabled, request metadata when startup. 55 // when kafka enabled, request metadata when startup.
49 - if (_srs_config->get_kafka_enabled() && (ret = request_metadata()) != ERROR_SUCCESS) { 56 + if ((ret = request_metadata()) != ERROR_SUCCESS) {
50 srs_error("request kafka metadata failed. ret=%d", ret); 57 srs_error("request kafka metadata failed. ret=%d", ret);
51 return ret; 58 return ret;
52 } 59 }
@@ -65,8 +72,7 @@ int SrsKafkaProducer::start() @@ -65,8 +72,7 @@ int SrsKafkaProducer::start()
65 return ret; 72 return ret;
66 } 73 }
67 74
68 - std::string enabled = srs_bool2switch(_srs_config->get_kafka_enabled());  
69 - srs_trace("kafka worker ok, enabled:%s", enabled.c_str()); 75 + srs_info("kafka worker ok");
70 76
71 return ret; 77 return ret;
72 } 78 }
@@ -80,7 +86,26 @@ int SrsKafkaProducer::request_metadata() @@ -80,7 +86,26 @@ int SrsKafkaProducer::request_metadata()
80 { 86 {
81 int ret = ERROR_SUCCESS; 87 int ret = ERROR_SUCCESS;
82 88
83 - srs_info("update kafka metadata ok"); 89 + bool enabled = _srs_config->get_kafka_enabled();
  90 + if (!enabled) {
  91 + return ret;
  92 + }
  93 +
  94 + SrsConfDirective* brokers = _srs_config->get_kafka_brokers();
  95 + if (!brokers) {
  96 + srs_warn("ignore for empty brokers.");
  97 + return ret;
  98 + }
  99 +
  100 + srs_assert(!brokers->args.empty());
  101 + std::string broker = lb->select<string>(brokers->args);
  102 +
  103 + if (true) {
  104 + std::string senabled = srs_bool2switch(enabled);
  105 + std::string sbrokers = srs_join_vector_string(brokers->args, ",");
  106 + srs_trace("kafka ok, enabled:%s, brokers:%s, current:[%d]%s",
  107 + senabled.c_str(), sbrokers.c_str(), lb->current(), broker.c_str());
  108 + }
84 109
85 return ret; 110 return ret;
86 } 111 }
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
  32 +class SrsLbRoundRobin;
32 class SrsAsyncCallWorker; 33 class SrsAsyncCallWorker;
33 34
34 #ifdef SRS_AUTO_KAFKA 35 #ifdef SRS_AUTO_KAFKA
@@ -39,6 +40,7 @@ class SrsAsyncCallWorker; @@ -39,6 +40,7 @@ class SrsAsyncCallWorker;
39 class SrsKafkaProducer 40 class SrsKafkaProducer
40 { 41 {
41 private: 42 private:
  43 + SrsLbRoundRobin* lb;
42 SrsAsyncCallWorker* worker; 44 SrsAsyncCallWorker* worker;
43 public: 45 public:
44 SrsKafkaProducer(); 46 SrsKafkaProducer();
  1 +/*
  2 + The MIT License (MIT)
  3 +
  4 + Copyright (c) 2013-2015 SRS(simple-rtmp-server)
  5 +
  6 + Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 + this software and associated documentation files (the "Software"), to deal in
  8 + the Software without restriction, including without limitation the rights to
  9 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 + the Software, and to permit persons to whom the Software is furnished to do so,
  11 + subject to the following conditions:
  12 +
  13 + The above copyright notice and this permission notice shall be included in all
  14 + copies or substantial portions of the Software.
  15 +
  16 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 + */
  23 +
  24 +#include <srs_kernel_balance.hpp>
  25 +
  26 +SrsLbRoundRobin::SrsLbRoundRobin()
  27 +{
  28 + index = -1;
  29 + count = 0;
  30 +}
  31 +
  32 +SrsLbRoundRobin::~SrsLbRoundRobin()
  33 +{
  34 +}
  35 +
  36 +u_int32_t SrsLbRoundRobin::current()
  37 +{
  38 + return index;
  39 +}
  40 +
  1 +/*
  2 + The MIT License (MIT)
  3 +
  4 + Copyright (c) 2013-2015 SRS(simple-rtmp-server)
  5 +
  6 + Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 + this software and associated documentation files (the "Software"), to deal in
  8 + the Software without restriction, including without limitation the rights to
  9 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 + the Software, and to permit persons to whom the Software is furnished to do so,
  11 + subject to the following conditions:
  12 +
  13 + The above copyright notice and this permission notice shall be included in all
  14 + copies or substantial portions of the Software.
  15 +
  16 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 + */
  23 +
  24 +#ifndef SRS_KERNEL_AAC_HPP
  25 +#define SRS_KERNEL_AAC_HPP
  26 +
  27 +/*
  28 +#include <srs_kernel_balance.hpp>
  29 +*/
  30 +#include <srs_core.hpp>
  31 +
  32 +#include <vector>
  33 +
  34 +/**
  35 + * the round-robin load balance algorithm,
  36 + * used for edge pull, kafka and other multiple server feature.
  37 + */
  38 +class SrsLbRoundRobin
  39 +{
  40 +private:
  41 + // current selected index.
  42 + int index;
  43 + // total scheduled count.
  44 + u_int32_t count;
  45 +public:
  46 + SrsLbRoundRobin();
  47 + virtual ~SrsLbRoundRobin();
  48 +public:
  49 + virtual u_int32_t current();
  50 +public:
  51 + template<typename T>
  52 + const T& select(const std::vector<T>& servers)
  53 + {
  54 + srs_assert(!servers.empty());
  55 +
  56 + index = (int)(count++ % servers.size());
  57 +
  58 + return servers.at(index);
  59 + }
  60 +};
  61 +
  62 +#endif
  63 +