失踪人口回归之Java开发工程师面试记录第一篇
大家好,我是DaiYuMeng,我回来了,这几年过得真是跌宕起伏了。总而言之,言而总之,本人目前还是在找java开发的工作,于是就有了面试,于是就有了本帖的诞生。好久没写帖子了哈哈,希望陪伴大家一起进步~~~
本博文是这样的一个模式:
一开始我会列举一下这些问题,大家可以思考一下,然后我会在第二个部分中写一下我的理解,以及会在最后一个模块中写出更为权威一点的答案。
一、思考时间
- 分布式锁怎么实现?
- 分布式锁和普通锁有什么区别?
- mysql幻读是什么?如何解决mysql幻读?
- 事物的隔离机制有哪些?
- 事务有哪些传播行为?
- 有哪些分布式解决方案?
- Seata有哪些机制?
- 乐观锁和悲观锁有什么区别?
- 分布式的base理论是什么?
- aop是什么?里面包含什么?
- 负载均衡算法举例?
- linux命令举例?
- tcp和udp的区别是什么?
- tranzient关键字是什么?
- mysql的第三范式是什么?
- 索引的最左适配原则是什么?
- 描述shiro的运行流程?
- 事务什么情况下会失效?
- 事务传播机制有哪些?
- 微服务和分布式的区别有哪些?
- 如何保证缓存和数据库的一致性?
- hashmap的原理是什么?concurrenthashmap的原理是什么?
- 谈论一下集合都有哪些?
- 说一下数据库怎么优化?
- 索引失效的原因有哪些?
- 谈论一下springboot的自动装配原理是什么?
- 说一下springboot2和springboot3的区别?
- 讲一下什么是redis的哨兵机制
- 什么是装箱和拆箱?
- 有三个微服务,a调用b,b调用c,b是单点服务,现在b挂了,要继续执行完这个服务,应该怎么处理(考核微服务中的限流和熔断)
二、作者回答时间(不一定对啊)
- 分布式锁怎么实现?答:①是mysql里的悲观锁实现分布式锁 ②是redis实现分布式锁,用redis中的setnx命令,以及redis里的redission框架③是通过mq实现分布式锁,这个不是特别了解
- 分布式锁和普通锁有什么区别?答:分布式锁的性能比普通锁要强,分布式锁可以用redis的setnx或者redission框架来实现,普通锁一般用lock或者synchronized来实现,其他的不是特别了解
- mysql幻读是什么?如何解决mysql幻读?答:mysql幻读举个例子就是比如有a,b两个事物,a和b共同操作一个账户c,a向c取了钱比如100元,然后b向c转了钱比如50元,然后b查询账户c发现自己明明转了50怎么钱还变少了50元;解决mysql幻读的方法有间隙锁,mvcc多版本并发控制等
- 事物的隔离机制有哪些?答:事务的隔离机制有4种,读未提交RU、读已提交RC、可重复读RR和串行化,其中Mysql默认的事务隔离级别的可重复读RR,Oracle默认的事务隔离级别是读已提交RC。
- 事务有哪些传播行为?答:事务的传播行为有7种,分别是默认propogation_support、propogation_support_new,propogation_never,propogation_mandatory、propogation_not_support、propogation_nested
- 有哪些分布式解决方案?答:比如seata
- Seata有哪些机制?答:比如TCC模式、SAGA模式等,具体的TCC模式就是Try、Confirm、Concel模式
- 乐观锁和悲观锁有什么区别?答:乐观锁默认多线程情况下不存在并发问题,所以一般不会加锁;悲观锁默认多线程情况下存在并发问题,所以每次都会加锁
- 分布式的base理论是什么?答:base理论分为强一致性、高可用性和,容错性,base理论就是至少要保证一致性和容错性或者高可用性和容错性(好像和cap理论搞混了,我目前太菜了。。)
- aop是什么?里面包含什么?答:aop是反向代理,里面包含切点、切面等等,有点不记得了
- 负载均衡算法举例?答:这个真忘了,不知道咋回答
- linux命令举例?答:ll和ls查看文件夹有哪些文件,mkdir创建文件,rm删除,rm-rf强制删除,还有pwd,不过pwd干嘛的忘记了
- tcp和udp的区别是什么?答:tcp对于可靠性有很强的要求,一般用于银行相关的业务中,udp对于可靠性没有要求,一般用于视频通过类似的业务中
- tranzient关键字是什么?答:这个忘记了
- mysql的第三范式是什么?答:第一范式是原子性,第二范式是唯一性,第三范式每个字段都不能有其他字段派生出来,就是派生性
- 索引的最左适配原则是什么?答:语句从左到右执行,如果执行到左边满足条件,就不会执行右边,比如or语句
- 描述shiro的运行流程?答:不知道怎么用语言描述
- 事务什么情况下会失效?答:一是没有使用@transaction注解,二是没有将异常跑出去,三是有不匹配的事务传播行为
- 微服务和分布式的区别有哪些?答:我认为微服务是一个大的服务拆分成多个小的服务,分布式是多个小的服务部署在不同的计算机上
- 如何保证缓存和数据库的一致性?答:第一个方法是延迟双删,第二个方法是canal中间件
- hashmap的原理是什么?concurrenthashmap的原理是什么?答:hashmap的底层是数组和链表,当数组长度大于8,链表长度大于64的时候就会变成数据和红黑树,hashmap存储数据会使用到hash算法,这里涉及到hash冲突
- 谈论一下集合都有哪些?答:Collection接口里有AbstractList和Map,AbstractList里面包括list,list里面包括arraylist等等 map里面包括hashmap、currenthashmap等等,set里面包含treeset等等(记不清了,太菜了我)
- 说一下数据库怎么优化?答:数据库优化分为三个方面,一个是sql语句的优化,一个是sql结构的优化,一个是硬件方面的优化,sql语句的优化比如避免写select *,避免使用子连接改成使用左右连接
- 索引失效的原因有哪些?答:索引失效的原因有SQL语句中使用了LIKE通配符,SQL语句中使用了IN 或者 NOT IN,SQL语句中使用了表达式,索引字段选择错误,索引不符合最左匹配原则等等
- 谈论一下springboot的自动装配原理是什么?答:springboot的启动类上有一个@SpringBootApplication的注解,这个注解是一个复合注解实际上起自动装配功能的是@EnableAutoConfiguration注解,在springboot2中他将配置类的信息放置在MET-INF下的spring.factories文件里,在springboot3中他将配置类的信息放置在MET-INF下的一个文件里
- 说一下springboot2和springboot3的区别?答:在springboot2中他将配置类的信息放置在MET-INF下的spring.factories文件里,在springboot3中他将配置类的信息放置在MET-INF下的一个文件里;springboot3里抛弃了springboot2里的一些特性;springboot3对JDK的要求最低是17,而springboot2对JDK的要求最低是8
- 讲一下什么是redis的哨兵机制?答:哨兵机制就是redis服务里有主节点,有从节点,一个主节点有多个从节点,当主节点宕机时,重新从从节点选举一个当主节点,选举时超过一半的从节点同意,就拥护被选举的从节点重新成为主节点
- 什么是装箱和拆箱?答:装箱就是将普通类转变为包装类,比如int转为Integer,Char转为Character;相反,拆箱就是将包装类转为普通类,比如Integer转为int。
- 有三个微服务,a调用b,b调用c,b是单点服务,现在b挂了,要继续执行完这个服务,应该怎么处理(考核微服务中的限流和熔断)答:使用sentinel限流熔断。将服务进行降级
- docker是干嘛的?有什么常见命令?答:docker是一个工具,具体是啥的工具不知道怎么描述了。docker的常见命令有docker run xxx, docker start xxx,docker restart xxx, docker volume xxx,docker network xxx
三、正确答案(AI回答)
- 分布式锁怎么实现?
- 分布式锁和普通锁有什么区别?
- mysql幻读是什么?如何解决mysql幻读?
- 事物的隔离机制有哪些?
- 事务有哪些传播行为?
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; public class ServiceClass { @Transactional(propagation = Propagation.REQUIRED) public void methodRequired() { // 如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的事务 } @Transactional(propagation = Propagation.SUPPORTS) public void methodSupports() { // 如果当前存在事务,则加入该事务;如果不存在事务,则以非事务方式继续运行 } @Transactional(propagation = Propagation.MANDATORY) public void methodMandatory() { // 如果当前存在事务,则加入该事务;如果不存在事务,则抛出异常 } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodRequiresNew() { // 创建一个新的事务,如果当前存在事务,则将当前事务挂起 } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void methodNotSupported() { // 以非事务方式执行操作,并且如果当前存在事务,则将该事务挂起 } @Transactional(propagation = Propagation.NEVER) public void methodNever() { // 以非事务方式执行操作,如果当前存在事务,则抛出异常 } @Transactional(propagation = Propagation.NESTED) public void methodNested() { // 如果当前存在事务,则在嵌套事务内执行;如果当前不存在事务,则其行为类似于PROPAGATION_REQUIRED } }
- 有哪些分布式解决方案?
- Seata有哪些机制?
- 乐观锁和悲观锁有什么区别?
- 分布式的base理论是什么?
- aop是什么?里面包含什么?
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.ProceedingJoinPoint; @Aspect public class LoggingAspect { // 前置通知 @Before("execution(* com.example.service.*.*(..))") public void logBefore() { System.out.println("Logging before method execution"); } // 后置通知 @AfterReturning("execution(* com.example.service.*.*(..))") public void logAfterReturning() { System.out.println("Logging after method successfully executed"); } // 异常通知 @AfterThrowing("execution(* com.example.service.*.*(..))") public void logAfterThrowing() { System.out.println("Logging after method throws an exception"); } // 环绕通知 @Around("execution(* com.example.service.*.*(..))") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Logging around method start: " + joinPoint.getSignature().getName()); try { Object result = joinPoint.proceed(); System.out.println("Logging around method end: " + joinPoint.getSignature().getName()); return result; } catch (Throwable throwable) { System.out.println("Logging around method exception: " + throwable.getMessage()); throw throwable; } } }
- 负载均衡算法举例?
- linux命令举例?
- tcp和udp的区别是什么?
- transient关键字是什么?
import java.io.*; class SecureUser implements Serializable { private String username; private transient String password; public SecureUser(String username, String password) { this.username = username; this.password = password; } private void writeObject(ObjectOutputStream oos) throws IOException { // 默认序列化 oos.defaultWriteObject(); // 自定义序列化:对密码进行加密 oos.writeUTF(encrypt(password)); } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { // 默认反序列化 ois.defaultReadObject(); // 自定义反序列化:对密码进行解密 password = decrypt(ois.readUTF()); } private String encrypt(String data) { // 简单的加密逻辑(实际应用中应使用更强的加密算法) return new StringBuilder(data).reverse().toString(); } private String decrypt(String data) { // 简单的解密逻辑(实际应用中应使用更强的解密算法) return new StringBuilder(data).reverse().toString(); } @Override public String toString() { return "SecureUser{username='" + username + "', password='" + password + "'}"; } } public class CustomSerializationExample { public static void main(String[] args) throws IOException, ClassNotFoundException { // 创建一个 SecureUser 对象 SecureUser secureUser = new SecureUser("john_doe", "secretPassword"); // 序列化对象到文件 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("secure_user.ser"))) { oos.writeObject(secureUser); } // 反序列化对象从文件 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("secure_user.ser"))) { SecureUser deserializedUser = (SecureUser) ois.readObject(); System.out.println(deserializedUser); // 输出: SecureUser{username='john_doe', password='secretPassword'} } } }
- mysql的第三范式是什么?
- 索引的最左适配原则是什么?
- 描述shiro的运行流程?
[main] # 配置 SecurityManager securityManager = org.apache.shiro.mgt.DefaultSecurityManager # 配置 Realm myRealm = com.example.MyCustomRealm securityManager.realm = $myRealm # 配置 Cache Manager cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager securityManager.cacheManager = $cacheManager # 配置 Session Manager sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager securityManager.sessionManager = $sessionManager [urls] /login = anon /logout = logout /** = authc
- 事务什么情况下会失效?
Connection conn = null; try { conn = dataSource.getConnection(); conn.setAutoCommit(false); // 执行一些SQL操作 statement.executeUpdate("INSERT INTO users (name) VALUES ('Alice')"); statement.executeUpdate("INSERT INTO users (name) VALUES ('Bob')"); conn.commit(); // 提交事务 } catch (SQLException e) { if (conn != null) { try { conn.rollback(); // 发生异常时回滚事务 } catch (SQLException ex) { ex.printStackTrace(); } } } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
Connection conn = null; PreparedStatement pstmt = null; try { conn = dataSource.getConnection(); conn.setAutoCommit(false); String sql = "INSERT INTO users (name) VALUES (?)"; pstmt = conn.prepareStatement(sql); for (String name : names) { pstmt.setString(1, name); pstmt.addBatch(); } pstmt.executeBatch(); conn.commit(); } catch (SQLException e) { if (conn != null) { try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } } finally { if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
- 事务传播机制有哪些?
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service public class TransactionService { @Autowired private AnotherService anotherService; @Transactional(propagation = Propagation.REQUIRED) public void requiredExample() { // 当前没有事务时创建一个新事务; // 当前有事务时加入该事务。 anotherService.methodA(); } @Transactional(propagation = Propagation.SUPPORTS) public void supportsExample() { // 当前有事务时加入该事务; // 当前没有事务时以非事务方式运行。 anotherService.methodB(); } @Transactional(propagation = Propagation.MANDATORY) public void mandatoryExample() { // 必须在事务中运行,否则抛出异常。 anotherService.methodC(); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void requiresNewExample() { // 总是创建一个新事务,与外部事务无关。 anotherService.methodD(); } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void notSupportedExample() { // 不会在事务中运行,如果有事务则暂停。 anotherService.methodE(); } @Transactional(propagation = Propagation.NEVER) public void neverExample() { // 必须在非事务中运行,否则抛出异常。 anotherService.methodF(); } @Transactional(propagation = Propagation.NESTED) public void nestedExample() { // 在嵌套事务中运行,可以独立提交或回滚。 anotherService.methodG(); } } @Service class AnotherService { @Transactional(propagation = Propagation.REQUIRED) public void methodA() { // 方法逻辑 } @Transactional(propagation = Propagation.SUPPORTS) public void methodB() { // 方法逻辑 } @Transactional(propagation = Propagation.MANDATORY) public void methodC() { // 方法逻辑 } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodD() { // 方法逻辑 } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void methodE() { // 方法逻辑 } @Transactional(propagation = Propagation.NEVER) public void methodF() { // 方法逻辑 } @Transactional(propagation = Propagation.NESTED) public void methodG() { // 方法逻辑 } }
- 微服务和分布式的区别有哪些?
- 如何保证缓存和数据库的一致性?
@Autowired private RedisTemplate<String, Object> redisTemplate; public User getUserById(Long id) { String key = "user:" + id; // 尝试从缓存中获取用户信息 User user = (User) redisTemplate.opsForValue().get(key); if (user == null) { synchronized (this) { user = (User) redisTemplate.opsForValue().get(key); if (user == null) { // 缓存未命中,从数据库中查询 user = userRepository.findById(id).orElse(null); if (user != null) { // 将数据写入缓存 redisTemplate.opsForValue().set(key, user, 60, TimeUnit.MINUTES); } } } } return user; } public void updateUser(User user) { // 更新数据库 userRepository.save(user); // 删除缓存 String key = "user:" + user.getId(); redisTemplate.delete(key); }
- hashmap的原理是什么?concurrenthashmap的原理是什么?
import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapExample { public static void main(String[] args) { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("apple", 1); map.put("banana", 2); map.put("orange", 3); System.out.println(map.get("apple")); // 输出: 1 // 并发修改示例 Runnable task = () -> { for (int i = 0; i < 1000; i++) { map.put("counter", map.getOrDefault("counter", 0) + 1); } }; Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(map.get("counter")); // 输出: 2000 } }
- 谈论一下集合都有哪些?
Collection ├── List │ ├── ArrayList │ ├── LinkedList │ └── Vector │ └── Stack ├── Set │ ├── HashSet │ │ └── LinkedHashSet │ └── TreeSet └── Queue ├── PriorityQueue └── Deque ├── ArrayDeque └── LinkedList Map ├── HashMap │ └── LinkedHashMap ├── TreeMap ├── Hashtable └── ConcurrentHashMap
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class ListExample { public static void main(String[] args) { List<String> arrayList = new ArrayList<>(); arrayList.add("Apple"); arrayList.add("Banana"); System.out.println(arrayList.get(0)); // 输出: Apple List<String> linkedList = new LinkedList<>(); linkedList.add("Apple"); linkedList.add("Banana"); System.out.println(linkedList.get(0)); // 输出: Apple } }
import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.TreeSet; public class SetExample { public static void main(String[] args) { Set<String> hashSet = new HashSet<>(); hashSet.add("Apple"); hashSet.add("Banana"); System.out.println(hashSet.contains("Apple")); // 输出: true Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("Apple"); linkedHashSet.add("Banana"); System.out.println(linkedHashSet); // 输出: [Apple, Banana] Set<String> treeSet = new TreeSet<>(); treeSet.add("Apple"); treeSet.add("Banana"); System.out.println(treeSet); // 输出: [Apple, Banana] } }
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; public class MapExample { public static void main(String[] args) { Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("Apple", 1); hashMap.put("Banana", 2); System.out.println(hashMap.get("Apple")); // 输出: 1 Map<String, Integer> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("Apple", 1); linkedHashMap.put("Banana", 2); System.out.println(linkedHashMap); // 输出: {Apple=1, Banana=2} Map<String, Integer> treeMap = new TreeMap<>(); treeMap.put("Apple", 1); treeMap.put("Banana", 2); System.out.println(treeMap); // 输出: {Apple=1, Banana=2} } }
- 说一下数据库怎么优化?
-- 创建普通索引 CREATE INDEX idx_user_name ON users(name); -- 创建唯一索引 CREATE UNIQUE INDEX idx_email ON users(email); -- 创建复合索引 CREATE INDEX idx_user_age_gender ON users(age, gender);
EXPLAIN SELECT * FROM users WHERE age > 30 AND gender = 'male';
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'), ('Bob', 'bob@example.com'), ('Charlie', 'charlie@example.com');
- 索引失效的原因有哪些?
- 谈论一下springboot的自动装配原理是什么?
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
@Configuration @ConditionalOnClass(JdbcTemplate.class) public class JdbcAutoConfiguration { @Bean @ConditionalOnMissingBean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
com.example.MyAutoConfiguration org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
@Configuration(proxyBeanMethods = false) @ConditionalOnClass({ DataSource.class, HikariDataSource.class }) @EnableConfigurationProperties(DataSourceProperties.class) @Import({ DataSourcePoolMetadataProvidersConfiguration.class }) public class DataSourceAutoConfiguration { @Bean @ConditionalOnMissingBean public DataSource dataSource(DataSourceProperties properties) { return properties.initializeDataSourceBuilder().build(); } }
- 说一下springboot2和springboot3的区别?
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤逻辑 chain.doFilter(request, response); } @Override public void destroy() {} }
import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.FilterConfig; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤逻辑 chain.doFilter(request, response); } @Override public void destroy() {} }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
com.example.MyAutoConfiguration org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- 讲一下什么是redis的哨兵机制
# sentinel.conf port 26379 # Sentinel 默认监听端口 sentinel monitor mymaster 127.0.0.1 6379 2 # 监控名为 mymaster 的主节点,IP 为 127.0.0.1,端口为 6379,仲裁数为 2 sentinel down-after-milliseconds mymaster 5000 # 如果 5 秒内没有响应则认为该节点下线 sentinel failover-timeout mymaster 60000 # 故障转移超时时间为 60 秒 sentinel parallel-syncs mymaster 1 # 在故障转移期间,允许并行同步的从节点数量
Master: 192.168.1.1:6379 Slave1: 192.168.1.2:6379 Slave2: 192.168.1.3:6379
Sentinel1: 192.168.1.4:26379 Sentinel2: 192.168.1.5:26379 Sentinel3: 192.168.1.6:26379
- 什么是装箱和拆箱?
- 有三个微服务,a调用b,b调用c,b是单点服务,现在b挂了,要继续执行完这个服务,应该怎么处理(考核微服务中的限流和熔断)
<dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot2</artifactId> <version>1.7.0</version> </dependency>
resilience4j.circuitbreaker: instances: serviceB: registerHealthIndicator: true slidingWindowSize: 10 minimumNumberOfCalls: 5 permittedNumberOfCallsInHalfOpenState: 3 automaticTransitionFromOpenToHalfOpenEnabled: true waitDurationInOpenState: 5s failureRateThreshold: 50 eventConsumerBufferSize: 10
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker; import org.springframework.stereotype.Service; @Service public class ServiceA { @CircuitBreaker(name = "serviceB", fallbackMethod = "fallback") public String callServiceB() { // 调用 B 服务的逻辑 return restTemplate.getForObject("http://service-b/endpoint", String.class); } public String fallback(Throwable t) { // 降级逻辑 return "Service B is down, using fallback response."; } }
resilience4j.ratelimiter: instances: serviceB: limitForPeriod: 10 limitRefreshPeriod: 1s timeoutDuration: 500ms
import io.github.resilience4j.ratelimiter.annotation.RateLimiter; import org.springframework.stereotype.Service; @Service public class ServiceA { @RateLimiter(name = "serviceB", fallbackMethod = "rateLimitFallback") public String callServiceB() { // 调用 B 服务的逻辑 return restTemplate.getForObject("http://service-b/endpoint", String.class); } public String rateLimitFallback(Throwable t) { // 限流降级逻辑 return "Rate limit exceeded for Service B."; } }
@Service public class ServiceA { private final Cache<String, String> cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .build(); public String callServiceB() { String cachedResponse = cache.getIfPresent("serviceBResponse"); if (cachedResponse != null) { return cachedResponse; } else { try { String response = restTemplate.getForObject("http://service-b/endpoint", String.class); cache.put("serviceBResponse", response); return response; } catch (Exception e) { return "Cached or fallback response"; } } } }
@Service public class ServiceA { public String callServiceB() { try { return restTemplate.getForObject("http://service-b/endpoint", String.class); } catch (Exception e) { return "Static fallback response"; } } }
@Service public class ServiceA { @Async public CompletableFuture<String> callServiceBAsync() { try { ResponseEntity<String> response = restTemplate.getForEntity("http://service-b/endpoint", String.class); return CompletableFuture.completedFuture(response.getBody()); } catch (Exception e) { return CompletableFuture.completedFuture("Fallback response"); } } }
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
management: endpoints: web: exposure: include: health endpoint: health: show-details: always
最后感谢大家的观看,愿大家都能拿到心仪的OFFER,下篇博文再见啦~~~