2828import java .util .concurrent .ConcurrentMap ;
2929import java .util .concurrent .CopyOnWriteArrayList ;
3030import org .apache .rocketmq .broker .util .PositiveAtomicCounter ;
31+ import org .apache .rocketmq .common .BrokerConfig ;
3132import org .apache .rocketmq .common .constant .LoggerName ;
3233import org .apache .rocketmq .logging .org .slf4j .Logger ;
3334import org .apache .rocketmq .logging .org .slf4j .LoggerFactory ;
@@ -44,15 +45,23 @@ public class ProducerManager {
4445 new ConcurrentHashMap <>();
4546 private final ConcurrentMap <String , Channel > clientChannelTable = new ConcurrentHashMap <>();
4647 protected final BrokerStatsManager brokerStatsManager ;
48+ private final BrokerConfig brokerConfig ;
4749 private final PositiveAtomicCounter positiveAtomicCounter = new PositiveAtomicCounter ();
4850 private final List <ProducerChangeListener > producerChangeListenerList = new CopyOnWriteArrayList <>();
4951
5052 public ProducerManager () {
5153 this .brokerStatsManager = null ;
54+ this .brokerConfig = null ;
5255 }
5356
5457 public ProducerManager (final BrokerStatsManager brokerStatsManager ) {
5558 this .brokerStatsManager = brokerStatsManager ;
59+ this .brokerConfig = null ;
60+ }
61+
62+ public ProducerManager (final BrokerStatsManager brokerStatsManager , final BrokerConfig brokerConfig ) {
63+ this .brokerStatsManager = brokerStatsManager ;
64+ this .brokerConfig = brokerConfig ;
5665 }
5766
5867 public int groupSize () {
@@ -136,6 +145,39 @@ public void scanNotActiveChannel() {
136145 public boolean doChannelCloseEvent (final String remoteAddr , final Channel channel ) {
137146 boolean removed = false ;
138147 if (channel != null ) {
148+ if (this .brokerConfig != null && this .brokerConfig .isEnableFastChannelEventProcess ()) {
149+ List <String > groups = ClientChannelAttributeHelper .getProducerGroups (channel );
150+ if (this .brokerConfig .isPrintChannelGroups () && groups .size () >= 5 && groups .size () >= this .brokerConfig .getPrintChannelGroupsMinNum ()) {
151+ log .warn ("channel close event, too many producer groups one channel, {}, {}, {}" , groups .size (), remoteAddr , groups );
152+ }
153+ for (String group : groups ) {
154+ if (null == group || group .length () == 0 ) {
155+ continue ;
156+ }
157+ ConcurrentMap <Channel , ClientChannelInfo > clientChannelInfoTable = this .groupChannelTable .get (group );
158+ if (null == clientChannelInfoTable ) {
159+ continue ;
160+ }
161+ final ClientChannelInfo clientChannelInfo =
162+ clientChannelInfoTable .remove (channel );
163+ if (clientChannelInfo != null ) {
164+ clientChannelTable .remove (clientChannelInfo .getClientId ());
165+ removed = true ;
166+ log .info (
167+ "NETTY EVENT: remove channel[{}][{}] from ProducerManager groupChannelTable, producer group: {}" ,
168+ clientChannelInfo .toString (), remoteAddr , group );
169+ callProducerChangeListener (ProducerGroupEvent .CLIENT_UNREGISTER , group , clientChannelInfo );
170+ if (clientChannelInfoTable .isEmpty ()) {
171+ ConcurrentMap <Channel , ClientChannelInfo > oldGroupTable = this .groupChannelTable .remove (group );
172+ if (oldGroupTable != null ) {
173+ log .info ("unregister a producer group[{}] from groupChannelTable" , group );
174+ callProducerChangeListener (ProducerGroupEvent .GROUP_UNREGISTER , group , null );
175+ }
176+ }
177+ }
178+ }
179+ return removed ; // must return here, degrade to scanNotActiveChannel at worst.
180+ }
139181 for (final Map .Entry <String , ConcurrentMap <Channel , ClientChannelInfo >> entry : this .groupChannelTable .entrySet ()) {
140182 final String group = entry .getKey ();
141183 final ConcurrentMap <Channel , ClientChannelInfo > clientChannelInfoTable = entry .getValue ();
@@ -162,20 +204,37 @@ public boolean doChannelCloseEvent(final String remoteAddr, final Channel channe
162204 }
163205
164206 public void registerProducer (final String group , final ClientChannelInfo clientChannelInfo ) {
207+
208+ long start = System .currentTimeMillis ();
165209 ClientChannelInfo clientChannelInfoFound ;
166210
167211 ConcurrentMap <Channel , ClientChannelInfo > channelTable = this .groupChannelTable .get (group );
212+ // note that we must take care of the exist groups and channels,
213+ // only can return when groups or channels not exist.
214+ if (this .brokerConfig != null
215+ && !this .brokerConfig .isEnableRegisterProducer ()
216+ && this .brokerConfig .isRejectTransactionMessage ()) {
217+ boolean needRegister = true ;
218+ if (null == channelTable ) {
219+ needRegister = false ;
220+ } else {
221+ clientChannelInfoFound = channelTable .get (clientChannelInfo .getChannel ());
222+ if (null == clientChannelInfoFound ) {
223+ needRegister = false ;
224+ }
225+ }
226+ if (!needRegister ) {
227+ if (null != this .brokerStatsManager ) {
228+ this .brokerStatsManager .incProducerRegisterTime ((int ) (System .currentTimeMillis () - start ));
229+ }
230+ return ;
231+ }
232+ }
233+
168234 if (null == channelTable ) {
169235 channelTable = new ConcurrentHashMap <>();
170- // Make sure channelTable will NOT be cleaned by #scanNotActiveChannel
171- channelTable .put (clientChannelInfo .getChannel (), clientChannelInfo );
172236 ConcurrentMap <Channel , ClientChannelInfo > prev = this .groupChannelTable .putIfAbsent (group , channelTable );
173- if (null == prev ) {
174- // Add client-id to channel mapping for new producer group
175- clientChannelTable .put (clientChannelInfo .getClientId (), clientChannelInfo .getChannel ());
176- } else {
177- channelTable = prev ;
178- }
237+ channelTable = prev != null ? prev : channelTable ;
179238 }
180239
181240 clientChannelInfoFound = channelTable .get (clientChannelInfo .getChannel ());
@@ -184,12 +243,19 @@ public void registerProducer(final String group, final ClientChannelInfo clientC
184243 channelTable .put (clientChannelInfo .getChannel (), clientChannelInfo );
185244 clientChannelTable .put (clientChannelInfo .getClientId (), clientChannelInfo .getChannel ());
186245 log .info ("new producer connected, group: {} channel: {}" , group , clientChannelInfo .toString ());
246+ if (this .brokerConfig != null && this .brokerConfig .isEnableFastChannelEventProcess ()) {
247+ ClientChannelAttributeHelper .addProducerGroup (clientChannelInfo .getChannel (), group );
248+ }
187249 }
188250
189251 // Refresh existing client-channel-info update-timestamp
190252 if (clientChannelInfoFound != null ) {
191253 clientChannelInfoFound .setLastUpdateTimestamp (System .currentTimeMillis ());
192254 }
255+
256+ if (null != this .brokerStatsManager ) {
257+ this .brokerStatsManager .incProducerRegisterTime ((int ) (System .currentTimeMillis () - start ));
258+ }
193259 }
194260
195261 public void unregisterProducer (final String group , final ClientChannelInfo clientChannelInfo ) {
0 commit comments