### Java: RPC Server Setup and Client Invocation Example Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This example illustrates a basic RPC setup, where a server registers the 'TinterfaceImpl' and starts listening on port 10000. A client then obtains a remote proxy for 'Tinterface' and invokes its 'send' method, demonstrating a successful remote call. ```Java import java.net.InetSocketAddress; public class RunTest { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { RPCServer rpcServer = new RPCServer(); rpcServer.register(Tinterface.class, TinterfaceImpl.class); rpcServer.start(10000); } }).start(); Tinterface tinterface = RPCclient.getRemoteProxyObj(Tinterface.class, new InetSocketAddress("localhost", 10000)); System.out.println(tinterface.send("rpc 测试用例")); } } ``` -------------------------------- ### Sentinel Nacos Flow Rule JSON Example Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/how-to-limit-current.md An example JSON configuration for a Sentinel flow control rule, typically stored in Nacos. This rule limits the '/hello' resource to 1 QPS, applying to all callers ('default'). ```JSON [ { "resource": "/hello", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ] ``` -------------------------------- ### Java Spring Boot REST Service Provider Example Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This Java code snippet illustrates how to define a RESTful API endpoint in a Spring Boot microservice. It uses @RestController and @RequestMapping to expose a GET method at /communication/hello, which returns a simple string, demonstrating a basic service interface. ```java @RestController @RequestMapping("/communication") public class RestControllerDemo { @GetMapping("/hello") public String s() { return "hello"; } } ``` -------------------------------- ### Hystrix Command Timeout and Fallback Example in Java Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-timeout.md This comprehensive Java example demonstrates a `HystrixCommand` (`GetProductInfoCommand`) configured with a 500ms timeout. The `run()` method simulates a 1-second delay, intentionally exceeding the timeout, which then triggers the `getFallback()` method to return default product information, showcasing Hystrix's resilience. ```java public class GetProductInfoCommand extends HystrixCommand { private Long productId; private static final HystrixCommandKey KEY = HystrixCommandKey.Factory.asKey("GetProductInfoCommand"); public GetProductInfoCommand(Long productId) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ProductInfoService")) .andCommandKey(KEY) .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() .withCoreSize(8) .withMaxQueueSize(10) .withQueueSizeRejectionThreshold(8)) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withCircuitBreakerEnabled(true) .withCircuitBreakerRequestVolumeThreshold(20) .withCircuitBreakerErrorThresholdPercentage(40) .withCircuitBreakerSleepWindowInMilliseconds(3000) // 设置是否打开超时,默认是true .withExecutionTimeoutEnabled(true) // 设置超时时间,默认1000(ms) .withExecutionTimeoutInMilliseconds(500) .withFallbackIsolationSemaphoreMaxConcurrentRequests(30))); this.productId = productId; } @Override protected ProductInfo run() throws Exception { System.out.println("调用接口查询商品数据,productId=" + productId); // 休眠1s TimeUtils.sleep(1); String url = "http://localhost:8081/getProductInfo?productId=" + productId; String response = HttpClientUtils.sendGetRequest(url); System.out.println(response); return JSONObject.parseObject(response, ProductInfo.class); } @Override protected ProductInfo getFallback() { ProductInfo productInfo = new ProductInfo(); productInfo.setName("降级商品"); return productInfo; } } ``` -------------------------------- ### Executing HystrixCommand.run() for Single Result Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md An example of executing a HystrixCommand to retrieve a single product information, which internally invokes the run() method. ```Java // 通过command执行,获取最新一条商品数据 ProductInfo productInfo = getProductInfoCommand.execute(); ``` -------------------------------- ### Java Spring Boot REST Service Consumer Example Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This Java code demonstrates how a microservice can consume an external REST API using Spring's RestTemplate. It shows dependency injection of RestTemplate and its use to make a GET request to http://localhost:9013/communication/hello, retrieving and returning the response from another service. ```java @RestController @RequestMapping("/demo") public class RestDemo{ @Autowired RestTemplate restTemplate; @GetMapping("/hello2") public String s2() { String forObject = restTemplate.getForObject("http://localhost:9013/communication/hello", String.class); return forObject; } } ``` -------------------------------- ### HTTP Request to Query Product Information Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-request-cache.md This HTTP GET request demonstrates how to query multiple product IDs from a local service. It's used to observe the initial data fetching and subsequent caching behavior of the backend system. ```HTTP http://localhost:8080/getProductInfos?productIds=1,1,1,2,2,5 ``` -------------------------------- ### HystrixCommand Product Info Service Example with Circuit Breaker Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-circuit-breaker.md Provides a concrete Java implementation of a HystrixCommand subclass, GetProductInfoCommand, demonstrating how to configure various circuit breaker properties such as requestVolumeThreshold, errorThresholdPercentage, and sleepWindowInMilliseconds. It includes a run() method to simulate service calls and an getFallback() method for graceful degradation, specifically simulating an error when productId is -1. ```Java public class GetProductInfoCommand extends HystrixCommand { private Long productId; private static final HystrixCommandKey KEY = HystrixCommandKey.Factory.asKey("GetProductInfoCommand"); public GetProductInfoCommand(Long productId) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ProductInfoService")) .andCommandKey(KEY) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // 是否允许断路器工作 .withCircuitBreakerEnabled(true) // 滑动窗口中,最少有多少个请求,才可能触发断路 .withCircuitBreakerRequestVolumeThreshold(20) // 异常比例达到多少,才触发断路,默认50% .withCircuitBreakerErrorThresholdPercentage(40) // 断路后多少时间内直接reject请求,之后进入half-open状态,默认5000ms .withCircuitBreakerSleepWindowInMilliseconds(3000))); this.productId = productId; } @Override protected ProductInfo run() throws Exception { System.out.println("调用接口查询商品数据,productId=" + productId); if (productId == -1L) { throw new Exception(); } String url = "http://localhost:8081/getProductInfo?productId=" + productId; String response = HttpClientUtils.sendGetRequest(url); return JSONObject.parseObject(response, ProductInfo.class); } @Override protected ProductInfo getFallback() { ProductInfo productInfo = new ProductInfo(); productInfo.setName("降级商品"); return productInfo; } } ``` -------------------------------- ### Dubbo Service Degradation: HelloService Mock Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-service-management.md Provides an example of a 'HelloServiceMock' class, which implements the 'HelloService' interface. This class defines custom fallback logic that will be executed when the primary service is unavailable or fails, as configured by Dubbo's mock mechanism. ```Java public class HelloServiceMock implements HelloService { public void sayHello() { // 降级逻辑 } } ``` -------------------------------- ### Spring Session Example Controller for Session Operations Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/distributed-session.md This Java Spring Boot REST controller demonstrates how to interact with sessions when Spring Session is configured. It includes two endpoints: `putIntoSession` to store data in the session and `getFromSession` to retrieve data, showing that native `HttpServletRequest.getSession()` calls seamlessly work with Spring Session's Redis backend. ```Java @RestController @RequestMapping("/test") public class TestController { @RequestMapping("/putIntoSession") public String putIntoSession(HttpServletRequest request, String username) { request.getSession().setAttribute("name", "leo"); return "ok"; } @RequestMapping("/getFromSession") public String getFromSession(HttpServletRequest request, Model model){ String name = request.getSession().getAttribute("name"); return name; } } ``` -------------------------------- ### Java Circuit Breaker Test Output Example Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-circuit-breaker.md This output demonstrates the circuit breaker's behavior during the test. Initially, 21 requests result in fallback responses due to the circuit opening. Subsequent requests (up to 30) also hit the fallback. After a 3-second sleep and transition to half-open, successful requests (productId=1) cause the circuit to close, leading to normal product information retrieval. ```Java 调用接口查询商品数据,productId=-1 ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) // ... // 这里重复打印了 20 次上面的结果 ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) // ... // 这里重复打印了 8 次上面的结果 // 休眠 3s 后 调用接口查询商品数据,productId=1 ProductInfo(id=1, name=iphone7手机, price=5599.0, pictureList=a.jpg,b.jpg, specification=iphone7的规格, service=iphone7的售后服务, color=红色,白色,黑色, size=5.5, shopId=1, modifiedTime=2017-01-01 12:00:00, cityId=1, cityName=null, brandId=1, brandName=null) // ... // 这里重复打印了 69 次上面的结果 ``` -------------------------------- ### Redis Strings: Basic Key-Value Operations Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-data-types.md Demonstrates the most fundamental Redis data type, Strings, used for simple key-value caching. The example shows how to set a string value for a given key. ```bash set college szu ``` -------------------------------- ### Dubbo Service Degradation: HelloService Interface and Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-service-management.md Defines a simple 'HelloService' interface and its 'HelloServiceImpl' implementation. These classes are used as a basic example to demonstrate service degradation concepts in Dubbo. ```Java public interface HelloService { void sayHello(); } public class HelloServiceImpl implements HelloService { public void sayHello() { System.out.println("hello world......"); } } ``` -------------------------------- ### Configure Dubbo Failsafe Cluster Strategy Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-load-balancing.md XML configuration examples for applying the Failsafe Cluster strategy in Dubbo. This strategy ignores exceptions upon failure and is typically used for non-critical interface calls, such as logging, where errors can be safely disregarded. ```XML ``` ```XML ``` -------------------------------- ### Configure Redis Diskless Replication Sync Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-master-slave.md Configures Redis master to perform diskless replication, where the RDB file is streamed directly to slaves without being written to the master's disk. The `repl-diskless-sync-delay` parameter specifies a delay before starting replication to allow more slaves to connect. ```bash repl-diskless-sync yes # 等待 5s 后再开始复制,因为要等更多 slave 重新连接过来 repl-diskless-sync-delay 5 ``` -------------------------------- ### Configure Dubbo Failover Cluster Retries Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-load-balancing.md XML configuration examples for setting the retry count for the Failover Cluster strategy in Dubbo. This strategy automatically retries other machines upon failure, commonly used for read operations. Retries can be configured at the service, reference, or specific method level. ```XML ``` ```XML ``` ```XML ``` -------------------------------- ### Redis Sorted Sets: Ordered Unique Data with Scores Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-data-types.md Explains Sorted Sets as unique collections where each member is associated with a score, allowing for automatic sorting. This data type is perfect for implementing leaderboards or ranked lists, demonstrating how to add members with scores and retrieve elements by rank or get a member's rank. ```bash zadd board 85 zhangsan zadd board 72 lisi zadd board 96 wangwu zadd board 63 zhaoliu # 获取排名前三的用户(默认是升序,所以需要 rev 改为降序) zrevrange board 0 3 # 获取某用户的排名 zrank board zhaoliu ``` -------------------------------- ### Creating HystrixCommand and HystrixObservableCommand Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md Illustrates the instantiation of HystrixCommand for single-result calls and HystrixObservableCommand for multi-result calls, demonstrating their basic constructor usage. ```Java // 创建 HystrixCommand HystrixCommand hystrixCommand = new HystrixCommand(arg1, arg2); // 创建 HystrixObservableCommand HystrixObservableCommand hystrixObservableCommand = new HystrixObservableCommand(arg1, arg2); ``` -------------------------------- ### Executing Hystrix Commands with Different Methods Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md Demonstrates the four primary methods for executing Hystrix commands: execute() for synchronous blocking, queue() for asynchronous Future-based execution, observe() for subscribing to an Observable copy, and toObservable() for obtaining an Observable that requires manual subscription. ```Java K value = hystrixCommand.execute(); Future fValue = hystrixCommand.queue(); Observable oValue = hystrixObservableCommand.observe(); Observable toOValue = hystrixObservableCommand.toObservable(); ``` -------------------------------- ### Small E-commerce Site Product Detail Page HTML Template Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/e-commerce-website-detail-page-architecture.md This HTML template demonstrates a simple structure for product detail pages in small e-commerce websites. It utilizes placeholders (e.g., #{productName}) for dynamic content insertion during the static page generation process, which is then served directly to users. ```html 商品名称:#{productName}
商品价格:#{productPrice}
商品描述:#{productDesc} ``` -------------------------------- ### Spring Cloud Gateway Rate Limiter Dependencies Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/how-to-limit-current.md Maven dependencies required to enable Spring Cloud Gateway with Redis-based rate limiting. Includes the gateway starter and reactive Redis data starter for integration. ```XML org.springframework.cloud spring-cloud-starter-gateway org.springframework.boot spring-boot-starter-data-redis-reactive ``` -------------------------------- ### Executing HystrixObservableCommand.construct() for Multiple Results Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md Demonstrates how to use observe() with HystrixObservableCommand to handle streams of data, subscribing to the Observable to process multiple results as they become available, with callbacks for completion, error, and next item. ```Java Observable observable = getProductInfosCommand.observe(); // 订阅获取多条结果 observable.subscribe(new Observer() { @Override public void onCompleted() { System.out.println("获取完了所有的商品数据"); } @Override public void onError(Throwable e) { e.printStackTrace(); } /** * 获取完一条数据,就回调一次这个方法 * * @param productInfo 商品信息 */ @Override public void onNext(ProductInfo productInfo) { System.out.println(productInfo); } }); ``` -------------------------------- ### Sentinel Spring Cloud Alibaba Dependency Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/how-to-limit-current.md Maven dependency for integrating Sentinel with Spring Cloud Alibaba, enabling robust flow control, circuit breaking, and other resilience features for microservices. ```XML com.alibaba.cloud spring-cloud-starter-alibaba-sentinel ``` -------------------------------- ### Configure Hystrix Command for Product Info Service with Thread Pool Limits Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-thread-pool-current-limiting.md Defines a HystrixCommand for fetching product info. It sets a thread pool size of 8, a waiting queue of 10, and a rejection threshold of 12. Includes a 20s timeout and circuit breaker. The `run` method simulates delays and fetches data, while `getFallback` handles failures. ```java public class GetProductInfoCommand extends HystrixCommand { private Long productId; private static final HystrixCommandKey KEY = HystrixCommandKey.Factory.asKey("GetProductInfoCommand"); public GetProductInfoCommand(Long productId) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ProductInfoService")) .andCommandKey(KEY) // 线程池相关配置信息 .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() // 设置线程池大小为8 .withCoreSize(8) // 设置等待队列大小为10 .withMaxQueueSize(10) .withQueueSizeRejectionThreshold(12)) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withCircuitBreakerEnabled(true) .withCircuitBreakerRequestVolumeThreshold(20) .withCircuitBreakerErrorThresholdPercentage(40) .withCircuitBreakerSleepWindowInMilliseconds(3000) // 设置超时时间 .withExecutionTimeoutInMilliseconds(20000) // 设置fallback最大请求并发数 .withFallbackIsolationSemaphoreMaxConcurrentRequests(30))); this.productId = productId; } @Override protected ProductInfo run() throws Exception { System.out.println("调用接口查询商品数据,productId=" + productId); if (productId == -1L) { throw new Exception(); } // 请求过来,会在这里hang住3秒钟 if (productId == -2L) { TimeUtils.sleep(3); } String url = "http://localhost:8081/getProductInfo?productId=" + productId; String response = HttpClientUtils.sendGetRequest(url); System.out.println(response); return JSONObject.parseObject(response, ProductInfo.class); } @Override protected ProductInfo getFallback() { ProductInfo productInfo = new ProductInfo(); productInfo.setName("降级商品"); return productInfo; } } ``` -------------------------------- ### Java: Generic Resource Closing Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This snippet demonstrates the essential practice of closing resources such as output streams, input streams, and network sockets. Proper resource closure is crucial to prevent resource leaks and ensure system stability, typically performed in a 'finally' block or using try-with-resources. ```Java out.close(); input.close(); socket.close(); ``` -------------------------------- ### Sentinel: Lightweight Flow Control and Reliability Component Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/micro-services-technology-stack.md Provides an overview of Alibaba Sentinel, a lightweight yet powerful Java library for flow control, circuit breaking, and reliability monitoring in microservices architectures. ```APIDOC A lightweight powerful flow control component enabling reliability and monitoring for microservices. (轻量级的流量控制、熔断降级 Java 库) ``` -------------------------------- ### Dubbo Consumer Configuration with Service Mocking Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-service-management.md XML configuration for a Dubbo service consumer. It registers the application, specifies the Zookeeper registry, and references a service ('FooService') with a 10-second timeout. Crucially, it demonstrates service mocking using 'mock="return null"' for graceful degradation, returning null on failure. ```XML ``` -------------------------------- ### Implement a Basic RPC TCP Client in Java Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This Java code defines an `RPCclient` that creates a dynamic proxy for remote service interfaces. When a method is called on the proxy, the client establishes a TCP connection to the RPC server, serializes the method name, parameter types, and arguments, sends them to the server, and then deserializes and returns the result. ```Java import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.InetSocketAddress; import java.net.Socket; /** * RPC 客户端 */ public class RPCclient { /** * 通过动态代理将参数发送过去到 RPCServer ,RPCserver 返回结果这个方法处理成为正确的实体 */ public static T getRemoteProxyObj(final Class service, final InetSocketAddress addr) { return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = null; ObjectOutputStream out = null; ObjectInputStream input = null; try { socket = new Socket(); socket.connect(addr); // 将实体类,参数,发送给远程调用方 out = new ObjectOutputStream(socket.getOutputStream()); out.writeUTF(service.getSimpleName()); out.writeUTF(method.getName()); out.writeObject(method.getParameterTypes()); out.writeObject(args); input = new ObjectInputStream(socket.getInputStream()); return input.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { ``` -------------------------------- ### Implement a Basic RPC TCP Server in Java Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This Java code defines an `RPCServer` that registers remote service implementations and listens for client connections. It uses a thread pool to handle concurrent requests, deserializes method calls, invokes the corresponding methods via reflection, and serializes the results back to the client. ```Java import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * RPC 服务端用来注册远程方法的接口和实现类 */ public class RPCServer { private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); private static final ConcurrentHashMap serviceRegister = new ConcurrentHashMap<>(); /** * 注册方法 * @param service * @param impl */ public void register(Class service, Class impl) { serviceRegister.put(service.getSimpleName(), impl); } /** * 启动方法 * @param port */ public void start(int port) { ServerSocket socket = null; try { socket = new ServerSocket(); socket.bind(new InetSocketAddress(port)); System.out.println("服务启动"); System.out.println(serviceRegister); while (true) { executor.execute(new Task(socket.accept())); } } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } private static class Task implements Runnable { Socket client = null; public Task(Socket client) { this.client = client; } @Override public void run() { ObjectInputStream input = null; ObjectOutputStream output = null; try { input = new ObjectInputStream(client.getInputStream()); // 按照顺序读取对方写过来的内容 String serviceName = input.readUTF(); String methodName = input.readUTF(); Class[] parameterTypes = (Class[]) input.readObject(); Object[] arguments = (Object[]) input.readObject(); Class serviceClass = serviceRegister.get(serviceName); if (serviceClass == null) { throw new ClassNotFoundException(serviceName + " 没有找到!"); } Method method = serviceClass.getMethod(methodName, parameterTypes); Object result = method.invoke(serviceClass.newInstance(), arguments); output = new ObjectOutputStream(client.getOutputStream()); output.writeObject(result); } catch (Exception e) { e.printStackTrace(); } finally { try { // 这里就不写 output!=null才关闭这个逻辑了 output.close(); input.close(); client.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` -------------------------------- ### Choosing Between RDB and AOF for Redis Persistence Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-persistence.md Provides guidance on selecting Redis persistence mechanisms. It advises against using RDB or AOF exclusively due to their respective limitations. The recommended approach is to combine both: AOF for primary data recovery and minimal data loss, and RDB for robust cold backups and faster full data restoration in extreme scenarios. ```APIDOC RDB and AOF Selection Guide: Recommendations: - Do not use RDB exclusively: Risk of significant data loss. - Do not use AOF exclusively: Slower cold backup recovery than RDB; AOF's complex merge/replay mechanism can be more fragile than RDB's simple snapshot. - Recommended Approach: Combine both RDB and AOF. - AOF: Primary choice for data recovery, ensuring minimal data loss. - RDB: Used for different levels of cold backups; provides fast data recovery if AOF files are lost or corrupted. ``` -------------------------------- ### Sentinel Nacos Data Source Configuration Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/how-to-limit-current.md YAML configuration for Sentinel to integrate with Nacos as a dynamic data source for rule management. It specifies the Nacos server address, Sentinel dashboard, and details for fetching flow rules from Nacos. ```YAML spring: cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: dashboard: localhost:8080 port: 8720 datasource: ds: nacos: server-addr: localhost:8848 dataId: spring-cloud-sentinel-nacos groupId: DEFAULT_GROUP rule-type: flow namespace: xxxxxxxx ``` -------------------------------- ### Console Output Showing Hystrix Caching Behavior Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-request-cache.md This console log illustrates the caching mechanism in action. Initial requests for a product ID result in a database call ('false' for cache), while subsequent requests for the same ID are served directly from the cache ('true' for cache), highlighting performance optimization. ```Text 调用接口查询商品数据,productId=1 是否是从缓存中取的结果:false 是否是从缓存中取的结果:true 是否是从缓存中取的结果:true 调用接口查询商品数据,productId=2 是否是从缓存中取的结果:false 是否是从缓存中取的结果:true 调用接口查询商品数据,productId=5 是否是从缓存中取的结果:false ``` -------------------------------- ### Company's Approach to Distributed Transactions (Interview Guidance) Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/distributed-transaction.md Provides practical advice on how to answer interview questions regarding distributed transaction solutions. It suggests a hybrid approach: using TCC for scenarios demanding strong consistency (e.g., financial transactions) and reliable message eventual consistency (e.g., via RocketMQ) for general business scenarios where data sensitivity is lower. ```APIDOC Interview Answer Strategy: - For extremely strict scenarios (e.g., critical financial transactions requiring strong consistency): Use TCC. - For general distributed transaction scenarios (e.g., order insertion and inventory update, where data is less sensitive than funds): Use reliable message eventual consistency (e.g., based on RocketMQ). - Example: 'For critical financial scenarios, we use TCC to ensure strong consistency. For other general scenarios, we implement distributed transactions based on Alibaba's RocketMQ.' ``` -------------------------------- ### Eureka Server: Service Registration (Register) API Call Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md Describes how a new service instance registers itself with the Eureka Server. This involves sending a POST request with instance information, which the server then processes by storing the instance locally and asynchronously replicating the registration to other Eureka Server peers. ```APIDOC HTTP Method: POST Endpoint: /eureka/v2/apps/{appName} Action: Register a new service instance. Internal Flow: 1. ApplicationResource.addInstance receives POST request. 2. Calls PeerAwareInstanceRegistryImpl.register. 3. AbstractInstanceRegistry.register stores instance information. 4. replicateToPeers asynchronously syncs registration to other Eureka Servers. Registry Structure: Map> ``` -------------------------------- ### Redis Lists: Simple Message Queue Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-data-types.md Shows how Redis Lists can be leveraged to create a basic message queue. Elements are pushed to the head of the list using `lpush` and consumed from the tail using `rpop`, providing a simple first-in, first-out (FIFO) mechanism. ```bash lpush mylist 1 lpush mylist 2 lpush mylist 3 4 5 # 1 rpop mylist ``` -------------------------------- ### Hystrix queue() Method Internal Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md Shows the underlying implementation of the queue() method, which transforms the command execution into a Future by calling toObservable().toBlocking().toFuture(). ```Java final Future delegate = toObservable().toBlocking().toFuture(); ``` -------------------------------- ### Obtaining Dubbo Adaptive Extension Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-spi.md This Java code demonstrates how Dubbo's ExtensionLoader is used to retrieve an adaptive extension instance for the Protocol interface. This mechanism allows Dubbo to dynamically select and load the appropriate Protocol implementation at runtime based on configuration or context. ```java Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); ``` -------------------------------- ### Controller for Batch Product Info Query with Hystrix Cache Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-request-cache.md This Spring MVC controller defines an endpoint /getProductInfos that accepts a comma-separated list of product IDs. For each product ID, it creates and executes a GetProductInfoCommand. The isResponseFromCache() method is used to demonstrate whether the command's result was retrieved from the Hystrix request cache, showcasing the optimization for duplicate product ID queries within a single request. ```Java @Controller public class CacheController { /** * 一次性批量查询多条商品数据的请求 * * @param productIds 以,分隔的商品id列表 * @return 响应状态 */ @RequestMapping("/getProductInfos") @ResponseBody public String getProductInfos(String productIds) { for (String productId : productIds.split(",")) { // 对每个productId,都创建一个command GetProductInfoCommand getProductInfoCommand = new GetProductInfoCommand(Long.valueOf(productId)); ProductInfo productInfo = getProductInfoCommand.execute(); System.out.println("是否是从缓存中取的结果:" + getProductInfoCommand.isResponseFromCache()); } return "success"; } } ``` -------------------------------- ### Apache Shiro: Java Security Framework Overview Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/micro-services-technology-stack.md Provides an overview of Apache Shiro, a powerful and easy-to-use Java security framework for authentication, authorization, cryptography, and session management across various application types. ```APIDOC Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications. ``` -------------------------------- ### Zuul: API Gateway Service for Microservices Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/micro-services-technology-stack.md Provides an overview of Netflix Zuul, a gateway service offering dynamic routing, monitoring, resiliency, and security features for microservices architectures. ```APIDOC Zuul is a gateway service that provides dynamic routing, monitoring, resiliency, security, and more. ``` -------------------------------- ### Redis Client-Server Communication Flow Source: https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-single-thread-model.md Illustrates the step-by-step communication process between a client and Redis, from connection establishment to command execution and response, leveraging the file event handler. ```APIDOC Client-Redis Communication Process: 1. Server Initialization: - Server socket's AE_READABLE event associated with Connection Acceptance Handler. 2. Client Connects (socket01): - Server socket generates AE_READABLE event. - IO Multiplexing Program pushes server socket to queue. - Event Dispatcher hands to Connection Acceptance Handler. - Handler creates client-specific socket01. - socket01's AE_READABLE event associated with Command Request Handler. 3. Client Sends Command (e.g., 'set key value'): - socket01 generates AE_READABLE event. - IO Multiplexing Program pushes socket01 to queue. - Event Dispatcher hands to Command Request Handler. - Handler reads command, executes 'set key value' in memory. - Handler associates socket01's AE_WRITABLE event with Command Reply Handler. 4. Redis Sends Reply (e.g., 'OK'): - socket01 generates AE_WRITABLE event (client ready to receive). - IO Multiplexing Program pushes socket01 to queue. - Event Dispatcher hands to Command Reply Handler. - Handler writes 'OK' to socket01. - Handler disassociates socket01's AE_WRITABLE event from Command Reply Handler. ``` -------------------------------- ### Ribbon: Client-Side Load Balancing Tool Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/micro-services-technology-stack.md Describes Spring Cloud Ribbon as a client-side load balancing tool based on Netflix Ribbon, supporting HTTP and TCP protocols for distributing requests among service instances. ```APIDOC Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具, 它基于 Netflix Ribbon 实现 ``` -------------------------------- ### Java: Hystrix Command for Brand Name Retrieval with Fallback Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-fallback.md This HystrixCommand simulates fetching a brand name. The `run()` method intentionally throws an exception to trigger the fallback mechanism. The `getFallback()` method then retrieves the brand name from the `BrandCache` (local memory), demonstrating a degradation strategy. It also configures a semaphore for fallback concurrency. ```Java /** * 获取品牌名称的command * */ public class GetBrandNameCommand extends HystrixCommand { private Long brandId; public GetBrandNameCommand(Long brandId) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("BrandService")) .andCommandKey(HystrixCommandKey.Factory.asKey("GetBrandNameCommand")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // 设置降级机制最大并发请求数 .withFallbackIsolationSemaphoreMaxConcurrentRequests(15))); this.brandId = brandId; } @Override protected String run() throws Exception { // 这里正常的逻辑应该是去调用一个品牌服务的接口获取名称 // 如果调用失败,报错了,那么就会去调用fallback降级机制 // 这里我们直接模拟调用报错,抛出异常 throw new Exception(); } @Override protected String getFallback() { return BrandCache.getBrandName(brandId); } } ``` -------------------------------- ### Java: Controller Demonstrating Hystrix Fallback Execution Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-fallback.md This Spring Controller endpoint demonstrates the usage of `GetBrandNameCommand`. It retrieves product information, extracts the brand ID, and then executes `GetBrandNameCommand`. Since the command's `run()` method is designed to fail, Hystrix will invoke its `getFallback()` method, showcasing the degradation in action. ```Java @Controller public class CacheController { @RequestMapping("/getProductInfo") @ResponseBody public String getProductInfo(Long productId) { HystrixCommand getProductInfoCommand = new GetProductInfoCommand(productId); ProductInfo productInfo = getProductInfoCommand.execute(); Long brandId = productInfo.getBrandId(); HystrixCommand getBrandNameCommand = new GetBrandNameCommand(brandId); // 执行会抛异常报错,然后走降级 String brandName = getBrandNameCommand.execute(); productInfo.setBrandName(brandName); System.out.println(productInfo); return "success"; } } ``` -------------------------------- ### Dubbo Provider Configuration for HelloService Source: https://github.com/doocs/advanced-java/blob/main/docs/distributed-system/dubbo-service-management.md XML configuration for a Dubbo service provider. It registers the application, specifies the Zookeeper registry address, defines the Dubbo protocol, and exposes the 'HelloService' interface with a 10-second timeout. ```XML ``` -------------------------------- ### Implementing Hystrix Request Context Filter Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-request-cache.md This Java class implements the Filter interface to manage the Hystrix Request Context lifecycle. It initializes a new HystrixRequestContext at the beginning of each web request and ensures it is properly shut down in the finally block, making the request context available for Hystrix commands throughout the request's duration. ```Java /** * Hystrix 请求上下文过滤器 */ public class HystrixRequestContextFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { filterChain.doFilter(servletRequest, servletResponse); } catch (IOException | ServletException e) { e.printStackTrace(); } finally { context.shutdown(); } } @Override public void destroy() { } } ``` -------------------------------- ### Hystrix execute() Method Internal Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-process.md Provides insight into the internal workings of the execute() method, revealing that it internally calls queue().get() to achieve synchronous execution. ```Java public R execute() { try { return queue().get(); } catch (Exception e) { throw Exceptions.sneakyThrow(decomposeException(e)); } } ``` -------------------------------- ### Java Spring Boot Circuit Breaker Test Class Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-circuit-breaker.md This Java Spring Boot test class simulates circuit breaker behavior. It sends 30 initial requests with `productId=-1` to trigger failures and open the circuit, then pauses for 3 seconds, and finally sends 70 requests with `productId=1` to demonstrate recovery and normal service calls. ```Java @SpringBootTest @RunWith(SpringRunner.class) public class CircuitBreakerTest { @Test public void testCircuitBreaker() { String baseURL = "http://localhost:8080/getProductInfo?productId="; for (int i = 0; i < 30; ++i) { // 传入-1,会抛出异常,然后走降级逻辑 HttpClientUtils.sendGetRequest(baseURL + "-1"); } TimeUtils.sleep(3); System.out.println("After sleeping..."); for (int i = 31; i < 100; ++i) { // 传入1,走服务正常调用 HttpClientUtils.sendGetRequest(baseURL + "1"); } } } ``` -------------------------------- ### Java: Defining RPC Interface and Implementation Source: https://github.com/doocs/advanced-java/blob/main/docs/micro-services/what's-microservice-how-to-communicate.md This code defines 'Tinterface', a simple interface for remote procedure calls, and 'TinterfaceImpl', its concrete implementation. The 'send' method within the interface is designed to be invoked remotely, returning a string message. ```Java public interface Tinterface { String send(String msg); } public class TinterfaceImpl implements Tinterface { @Override public String send(String msg) { return "send message " + msg; } } ``` -------------------------------- ### Console Output of Hystrix Rejection Test Results Source: https://github.com/doocs/advanced-java/blob/main/docs/high-availability/hystrix-thread-pool-current-limiting.md Displays the console output from the Hystrix rejection test. It shows 7 instances of '降级商品' (degraded product), confirming that requests exceeding the thread pool and queue capacity were rejected and triggered the fallback logic. Also includes successful request logs. ```text ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 调用接口查询商品数据,productId=-2 ProductInfo(id=null, name=降级商品, price=null, pictureList=null, specification=null, service=null, color=null, size=null, shopId=null, modifiedTime=null, cityId=null, cityName=null, brandId=null, brandName=null) {"id": -2, "name": "iphone7手机", "price": 5599, "pictureList":"a.jpg,b.jpg", "specification": "iphone7的规格", "service": "iphone7的售后服务", "color": "红色,白色,黑色", "size": "5.5", "shopId": 1, "modifiedTime": "2017-01-01 12:00:00", "cityId": 1, "brandId": 1} // 后面都是一些正常的商品信息,就不贴出来了 // ... ```