消息队列中间件
- Apache Kafka
- 使用过程:
- 引入依赖:在Maven项目中,添加相关依赖
<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.8.0</version></dependency>
。
- 生产者代码:
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
public class KafkaProducerExample {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", "key1", "value1");
producer.send(record);
producer.close();
}
}
- **消费者代码**:
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Collections;
import java.util.Properties;
public class KafkaConsumerExample {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("test-topic"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.println("Received message: " + record.value());
}
}
}
}
- **注意要点**:合理设置分区数和副本数,以满足性能和可靠性需求;注意消息的序列化和反序列化方式,确保数据的正确传输和处理;监控Kafka集群的性能指标,如吞吐量、延迟等。
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs', exchange_type='fanout')
message = "Hello, RabbitMQ!"
channel.basic_publish(exchange='logs', routing_key='', body=message)
connection.close()
- **创建消费者**:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs', exchange_type='fanout')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='logs', queue=queue_name)
def callback(ch, method, properties, body):
print("Received message: %r" % body)
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()
- **注意要点**:合理设计消息路由策略,根据业务需求选择合适的交换机类型和路由键;确保消息的持久化配置,避免消息丢失;注意内存和磁盘的使用情况,防止RabbitMQ服务器因资源不足而出现问题。
服务治理中间件
- Dubbo
- 使用过程:
- 定义公共接口:
package com.example.api;public interface UserService {String getUserById(String userId);}
- 实现服务提供者:
package com.example.provider;
import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboService;
@DubboService(version = "1.0.0")
public class UserServiceImpl implements UserService {
@Override
public String getUserById(String userId) {
return "User(id=" + userId + ",name=乔总)";
}
}
- **配置dubbo服务提供者**:在`application.yml`中配置dubbo和注册中心。
dubbo:
application:
name: user-service-provider
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
- **实现服务消费者**:
package com.example.consumer;
import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class UserServiceConsumer implements CommandLineRunner {
@DubboReference(version = "1.0.0")
private UserService userService;
@Override
public void run(String... args) {
String user = userService.getUserById("123");
System.out.println("Received user: " + user);
}
}
- **配置dubbo服务消费者**:在客户端的`application.yml`配置。
dubbo:
application:
name: user-service-consumer
registry:
address: zookeeper://127.0.0.1:2181
- **注意要点**:注意服务版本管理,避免因为版本不兼容导致服务调用失败;确保注册中心的高可用性,部署为高可用集群;合理调整服务调用的超时与重试机制。
- Nacos
- 使用过程:
- 服务注册:在服务提供者项目中,引入Nacos客户端依赖,在配置文件中配置Nacos服务器地址等信息,在启动类或配置类中使用相关注解或API进行服务注册。
- 服务发现:在服务消费者项目中,引入Nacos客户端依赖,配置Nacos服务器地址,使用Nacos提供的API获取服务实例列表,进行远程调用。
- 配置中心:在应用中引入Nacos配置客户端依赖,配置Nacos服务器地址,使用API或注解获取配置信息,实现动态更新。
- 注意要点:注意Nacos服务器的部署模式,根据实际需求选择单机或集群部署;合理设置命名空间、分组等,避免配置冲突;确保Nacos与其他组件的兼容性。
分布式事务中间件
- Seata
- 使用过程:
- AT模式:在微服务项目中引入Seata依赖,配置Seata服务器地址、事务分组等信息,在需要分布式事务的方法上添加
@GlobalTransactional
注解。
- TCC模式:定义TCC接口,包含
try
、confirm
和cancel
方法,实现TCC接口,在业务逻辑中调用TCC接口的方法。
- 注意要点:关注网络延迟和事务超时问题,避免事务长时间悬挂;处理好锁竞争,考虑使用乐观锁等机制;合理设置日志记录级别和存储方式,便于排查问题。
分布式数据库中间件
- ShardingSphere
- 使用过程:
- 引入依赖:在项目的
pom.xml
文件中引入ShardingSphere的相关依赖。
- 配置数据源:配置多个数据源,定义分片规则、读写分离规则等。
- 使用JDBC操作:使用JDBC的标准接口进行数据库操作,ShardingSphere会根据配置自动进行分片和读写分离。
- 注意要点:确保分片键的选择合理,避免数据倾斜;注意数据迁移和扩容的问题;监控数据库连接池的状态,防止连接泄漏。