mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-03 02:32:35 +01:00
mq(kafka): Phase 3 Step 1 - Consumer Group Foundation
- Implement comprehensive consumer group coordinator with state management - Add JoinGroup API (key 11) for consumer group membership - Add SyncGroup API (key 14) for partition assignment coordination - Create Range and RoundRobin assignment strategies - Support consumer group lifecycle: Empty -> PreparingRebalance -> CompletingRebalance -> Stable - Add automatic member cleanup and expired session handling - Comprehensive test coverage for consumer groups, assignment strategies - Update ApiVersions to advertise 9 APIs total (was 7) - All existing integration tests pass with new consumer group support This provides the foundation for distributed Kafka consumers with automatic partition rebalancing and group coordination, compatible with standard Kafka clients.
This commit is contained in:
1 parent
5aee693eac
commit
d415911943
16 files changed
+2374
-317
No files matched your search
@@ -1,31 +1,31 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/kafka/gateway"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/mq/kafka/gateway"
|
||||
)
|
||||
|
||||
var (
|
||||
mqKafkaGatewayOptions mqKafkaGatewayOpts
|
||||
mqKafkaGatewayOptions mqKafkaGatewayOpts
|
||||
)
|
||||
|
||||
type mqKafkaGatewayOpts struct {
|
||||
listen *string
|
||||
agentAddress *string
|
||||
seaweedMode *bool
|
||||
listen *string
|
||||
agentAddress *string
|
||||
seaweedMode *bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdMqKafkaGateway.Run = runMqKafkaGateway
|
||||
mqKafkaGatewayOptions.listen = cmdMqKafkaGateway.Flag.String("listen", ":9092", "Kafka gateway listen address")
|
||||
mqKafkaGatewayOptions.agentAddress = cmdMqKafkaGateway.Flag.String("agent", "", "SeaweedMQ Agent address (e.g., localhost:17777)")
|
||||
mqKafkaGatewayOptions.seaweedMode = cmdMqKafkaGateway.Flag.Bool("seaweedmq", false, "Use SeaweedMQ backend instead of in-memory stub")
|
||||
cmdMqKafkaGateway.Run = runMqKafkaGateway
|
||||
mqKafkaGatewayOptions.listen = cmdMqKafkaGateway.Flag.String("listen", ":9092", "Kafka gateway listen address")
|
||||
mqKafkaGatewayOptions.agentAddress = cmdMqKafkaGateway.Flag.String("agent", "", "SeaweedMQ Agent address (e.g., localhost:17777)")
|
||||
mqKafkaGatewayOptions.seaweedMode = cmdMqKafkaGateway.Flag.Bool("seaweedmq", false, "Use SeaweedMQ backend instead of in-memory stub")
|
||||
}
|
||||
|
||||
var cmdMqKafkaGateway = &Command{
|
||||
UsageLine: "mq.kafka.gateway [-listen=:9092] [-agent=localhost:17777] [-seaweedmq]",
|
||||
Short: "start a Kafka wire-protocol gateway for SeaweedMQ",
|
||||
Long: `Start a Kafka wire-protocol gateway translating Kafka client requests to SeaweedMQ.
|
||||
UsageLine: "mq.kafka.gateway [-listen=:9092] [-agent=localhost:17777] [-seaweedmq]",
|
||||
Short: "start a Kafka wire-protocol gateway for SeaweedMQ",
|
||||
Long: `Start a Kafka wire-protocol gateway translating Kafka client requests to SeaweedMQ.
|
||||
|
||||
By default, uses an in-memory stub for development and testing.
|
||||
Use -seaweedmq -agent=<address> to connect to a real SeaweedMQ Agent for production.
|
||||
@@ -35,42 +35,40 @@ This is experimental and currently supports a minimal subset for development.
|
||||
}
|
||||
|
||||
func runMqKafkaGateway(cmd *Command, args []string) bool {
|
||||
// Validate options
|
||||
if *mqKafkaGatewayOptions.seaweedMode && *mqKafkaGatewayOptions.agentAddress == "" {
|
||||
glog.Fatalf("SeaweedMQ mode requires -agent address")
|
||||
return false
|
||||
}
|
||||
// Validate options
|
||||
if *mqKafkaGatewayOptions.seaweedMode && *mqKafkaGatewayOptions.agentAddress == "" {
|
||||
glog.Fatalf("SeaweedMQ mode requires -agent address")
|
||||
return false
|
||||
}
|
||||
|
||||
srv := gateway.NewServer(gateway.Options{
|
||||
Listen: *mqKafkaGatewayOptions.listen,
|
||||
AgentAddress: *mqKafkaGatewayOptions.agentAddress,
|
||||
UseSeaweedMQ: *mqKafkaGatewayOptions.seaweedMode,
|
||||
})
|
||||
srv := gateway.NewServer(gateway.Options{
|
||||
Listen: *mqKafkaGatewayOptions.listen,
|
||||
AgentAddress: *mqKafkaGatewayOptions.agentAddress,
|
||||
UseSeaweedMQ: *mqKafkaGatewayOptions.seaweedMode,
|
||||
})
|
||||
|
||||
mode := "in-memory"
|
||||
if *mqKafkaGatewayOptions.seaweedMode {
|
||||
mode = "SeaweedMQ (" + *mqKafkaGatewayOptions.agentAddress + ")"
|
||||
}
|
||||
glog.V(0).Infof("Starting MQ Kafka Gateway on %s with %s backend", *mqKafkaGatewayOptions.listen, mode)
|
||||
if err := srv.Start(); err != nil {
|
||||
glog.Fatalf("mq kafka gateway start: %v", err)
|
||||
return false
|
||||
}
|
||||
mode := "in-memory"
|
||||
if *mqKafkaGatewayOptions.seaweedMode {
|
||||
mode = "SeaweedMQ (" + *mqKafkaGatewayOptions.agentAddress + ")"
|
||||
}
|
||||
glog.V(0).Infof("Starting MQ Kafka Gateway on %s with %s backend", *mqKafkaGatewayOptions.listen, mode)
|
||||
if err := srv.Start(); err != nil {
|
||||
glog.Fatalf("mq kafka gateway start: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Set up graceful shutdown
|
||||
defer func() {
|
||||
glog.V(0).Infof("Shutting down MQ Kafka Gateway...")
|
||||
if err := srv.Close(); err != nil {
|
||||
glog.Errorf("mq kafka gateway close: %v", err)
|
||||
}
|
||||
}()
|
||||
// Set up graceful shutdown
|
||||
defer func() {
|
||||
glog.V(0).Infof("Shutting down MQ Kafka Gateway...")
|
||||
if err := srv.Close(); err != nil {
|
||||
glog.Errorf("mq kafka gateway close: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Serve blocks until closed
|
||||
if err := srv.Wait(); err != nil {
|
||||
glog.Errorf("mq kafka gateway wait: %v", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
// Serve blocks until closed
|
||||
if err := srv.Wait(); err != nil {
|
||||
glog.Errorf("mq kafka gateway wait: %v", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user