Archives
All the articles I've archived.
Kafka (Part 7): Integrating Apache Avro and Apicurio Schema Registry to Ensure Message Compatibility Between Producers and Consumers
To address deserialization failures caused by Kafka message format changes, this article walks through migrating from JSON to Avro and integrating Apicurio Schema Registry. It covers schema definition, Java class generation, producer and consumer configuration, and version compatibility checks, reducing the risk of poison-pill messages.
Frontend Security: JavaScript Obfuscation, Request Encryption, and Signing to Make Scraping Harder
Introduces JavaScript obfuscation, request-body encryption, and request signing through examples, including RSA key exchange, AES-GCM encryption and decryption, and backend timestamp and nonce validation. It discusses increasing the cost of API analysis and reverse engineering, and balancing security with performance.
Understanding Java NIO (Part 3): I/O Multiplexing and the Reactor Pattern in Java, with Open-Source Framework Code Analysis
This post implements a Multi-Reactor server with Java NIO and explains how Channel, Buffer, Selector, and wakeup work together. It also covers cross-thread channel registration and dynamically adjusting read/write events, and analyzes how NIO is applied in the source code of Apache HttpClient and the Kafka client.
Managing and Updating Production Server Configuration in Batches with Ansible
Uses production server configuration updates to introduce an Ansible development environment, inventory, and playbook organization. Examples cover selecting host batches, copying and editing files, restarting services, and upgrading the kernel, with explanations of variables, conditions, and concurrent execution.
Understanding Java NIO (Part 2): I/O Multiplexing and Reactor Servers in C
Starting from the limitations of polling with nonblocking I/O, this post introduces select and epoll through C examples. It explains file descriptors, level-triggered and edge-triggered notifications, then combines connection management, I/O event handling, and a business thread pool into a Multi-Reactor server.
Understanding Java NIO (Part 1): Blocking I/O Servers in C with Processes, Threads, and Thread Pools
C implementations of blocking socket servers use a single process, multiple processes, multiple threads, and a thread pool to explain connection handling, file descriptors, and resource release. Comparing their concurrency and overhead establishes a foundation for nonblocking I/O and I/O multiplexing.
Replacing Database LIKE Queries with Elasticsearch: Approaches and Implementation Details
For a large order dataset, Elasticsearch replaces database LIKE searches on contact information, followed by database lookups for orders. The article covers index design, historical and incremental synchronization, UTC handling, pagination, database fallback, and synchronization gaps.
Python (Part 1): Building a WeChat Mini Program Bot for Scheduled Flash Sales and Setting Up a Maintainable Project
This article uses Charles to inspect a WeChat Mini Program’s API and builds a Python bot for scheduled orders, with results pushed to iOS through Bark. It also covers project scaffolding and dependency management, proxy selection, and optimizations involving multithreading, connection reuse, and request timing.
Enterprise JDK Upgrades (Part 1): Moving from JDK 11 to JDK 17
Using an upgrade of multiple company Java applications from JDK 11 to JDK 17, this article discusses compatibility checks and a staged migration. It covers changed exception messages, reflective-access restrictions, separate runtime and compile-time transitions, and supporting changes to Tomcat, Jenkins, and development environments.
JMX Exporter Source Analysis, Production Practices, and Scrape Timeout Troubleshooting
An investigation of JMX Exporter scrape timeouts compares MBean inclusion, rule caching, and attribute filtering. Source analysis and an extension allow querying only specified MBean attributes, followed by production configuration recommendations and the experience of contributing the change upstream.
Automating AWS EC2 Creation, Elasticsearch and Kibana Installation, and OpenTelemetry Monitoring
AWS CLI scripts create an EC2 instance and internal DNS record, while properties files and User Data organize deployment parameters and initialization. Using Elasticsearch, Kibana, and OpenTelemetry as examples, this article covers server configuration, automated deployment, and verification.
Locks in Java (Part 4): High-Performance Web Page Caching with a Read-Write Lock
Starting with Ehcache 2 web-caching source code, this article analyzes the role of ReentrantReadWriteLock in concurrent cache loading. It then discusses an Ehcache 3 migration and how a custom Filter, cache keys, and a read-write lock cooperate to handle concurrent requests for the same page.
A Practical Guide to Elasticsearch in Application Development, with a Real Optimization Case
A checklist for using Elasticsearch in application development, covering analyzer validation, field mappings, index planning, lifecycle management, and capacity estimates. A real logging use case illustrates performance problems caused by cleanup and writes, along with improvements using data streams, circuit breakers, and batching.
Building Elastic Stack from the Official Documentation: A Three-Node Elasticsearch Cluster, Kibana, Filebeat, Metricbeat, and Migration Without Downtime
Uses Docker Compose to build Elastic Stack with a three-node Elasticsearch cluster, Kibana, Filebeat, and Metricbeat, explaining TLS and monitoring configuration. Drawing on a production migration, it discusses moving from one node to a cluster through domain switching, data migration, and connection verification.
JDBC Streaming Reads and Correct Streaming Processing, with Examples
JDBC streaming reads.
Kafka (Part 6): Oracle-to-PostgreSQL CDC with Kafka Connect and Debezium, and Cache Consistency
Introduces CDC and synchronizes Oracle data to PostgreSQL through a Kafka Connect and Debezium example. It discusses database synchronization, Elasticsearch imports, and cache consistency, comparing the conditions under which different approaches are suitable.
Kafka (Part 5): Consumer Callbacks, Scheduled Retries, and Rebalancing
This largely completes a messaging system built with Kafka. The key code has been explained across the articles; see the source repository for the complete design and implementation. The next Kafka article is planned to cover synchronizing Oracle data to PostgreSQL with Kafka Connect.
Kafka (Part 4): Consuming JSON, Sharing a Deserializer, and Improving Throughput
This article implements Kafka consumers for JSON messages, including shared deserialization, deduplication, retries, and offset commits. Load tests inform partition counts and consumer settings, and the template method pattern reuses the consumption flow for emails of different priorities.
Kafka (Part 3): Sending JSON with a Shared Serializer and Improving Producer Throughput
Implements a Kafka producer that sends JSON messages, using a shared serializer for different objects and configuring asynchronous sending, failure recording, and retries. Based on actual email-message sizes, it discusses how compression, batch size, request size, and waiting time affect throughput.
Kafka (Part 2): Designing a Messaging System to Decouple Email Delivery
Uses email delivery to explain a design that decouples a business system from an email system through Kafka. It discusses responsibility boundaries, a unified message format, sending and callback flows, and a fallback when switching between old and new systems, providing background for subsequent producer and consumer implementations.
Load Testing HTTP APIs with JMeter (Part 1): Writing and Debugging Test Scripts
This article doesn't go into much detail about JMeter's components and their concepts; in my view, the official documentation is already the most essential learning material, and once you've configured a few scripts yourself you'll basically know what each component is for. If you want to learn JMeter, read the official documentation and look things up whenever a concept or setting is unclear — readers who are just getting started should also spend more time on the FAQ and Best Practices sections.
Kafka (Part 1): A Single-Node KRaft Setup with Docker Compose, Kafka UI, and Prometheus JMX Exporter
Builds a single-node Kafka environment in KRaft mode with Docker Compose and integrates Kafka UI and Prometheus JMX Exporter. It explains listeners, roles, memory, and monitoring configuration, then covers startup verification, JMX port conflicts, and resource-related troubleshooting.
Understanding HTTPS, TLS, and SSL (Part 2): Visualizing the TLS Handshake and Decrypting Traffic
After generating a self-signed certificate locally and configuring the browser to trust it, HTTPS hides request and response contents from Wireshark. Because I tended to forget the handshake analyses I had read, I decided to capture traffic myself and inspect the entire process.
Understanding HTTPS, TLS, and SSL (Part 1): Core Concepts and Local Self-Signed Certificates
I frequently encounter HTTPS, TLS, and SSL. After reading a few articles, I thought I understood them, but troubleshooting showed that I barely knew the basics. This post fills in that foundational knowledge without going deeply into interpreting the various standards.
Using Log4j2 (Part 3): Different Configurations for Different Environments
Explains ways to use different Log4j2 output formats and configurations across environments, including SystemPropertyArbiter, property substitution, custom Lookup plugins, and ScriptAppenderSelector. It discusses the choice between startup options and code extensions in the context of project deployment workflows.
Setting Up a C Development Environment in VS Code
Having used VS Code relatively little, I lacked experience developing C programs in it. This post records the steps for setting up a C development environment in VS Code.
Using Eclipse Krazo (Jakarta MVC)
An introduction to Jakarta MVC and its Eclipse Krazo implementation, using page access and form submission to explain controllers, models, views, redirects, and parameter validation. Source-code analysis traces CSRF token generation and validation, followed by a custom page for validation failures.
Programming Visualization Websites and Tools (Continuously Updated)
A collection of visualization websites and tools for understanding programming concepts, including Git practice, regular expression testing, Wireshark packet analysis, and shell command explanations. Interactive demonstrations and hands-on practice make it easier to understand how these concepts work and provide a reference for later use.
Shipping Tomcat access_logs from EC2 to Elasticsearch with Filebeat and AWS CloudWatch Logs, with Automated Log Management via ILM
In a log collection pipeline from CloudWatch Logs to Elasticsearch, Data Streams and ILM are used to manage index rollover and expiration-based deletion. Drawing on hands-on practice, this article describes the tuning process for Filebeat's memory queue, bulk write, and concurrency parameters, and records issues such as latency, cost, and occasional small amounts of log loss.
Implementing Rate-Limiting Algorithms with Lua Scripts
Lua scripts executed and debugged in Redis implement fixed-window, sliding-window, token-bucket, and leaky-bucket rate limiting. Request-count examples explain fixed-window boundary issues and discuss where the algorithms fit in rate limiting and traffic shaping.
Shipping Tomcat Access Logs from EC2 to ELK with Filebeat and AWS CloudWatch Logs
An end-to-end approach to sending Tomcat access logs from AWS EC2 to ELK: CloudWatch Agent collects the logs, Filebeat pulls them from CloudWatch Logs, and Logstash parses and indexes them in Elasticsearch. It covers configuration, pipeline verification, and troubleshooting.
Using Hibernate Validator (Part 1)
Introduces Hibernate Validator alongside the Jakarta Bean Validation specification, covering constraint annotations, cascading validation, and method parameter and return-value validation. English and Chinese error-message examples demonstrate internationalization, followed by an analysis of how RESTEasy switches validation messages according to the request language.
PostgreSQL (Part 2): Best Practices for Procedural Language Usage
Database server-side programming with PL/pgSQL.
Installing Software with Homebrew (Continuously Updated)
This post records how to install various software packages with Homebrew.
MySQL Notes
MySQL study and development notes covering connection methods, data types, primary keys and indexes, storage engines, and transaction isolation levels. Through examples it discusses dirty reads, non-repeatable reads, phantom reads, and locks, and also records execution plan analysis, SQL optimization, and the roles of common logs.
Docker Notes
Notes from using Docker.
PostgreSQL (Part 1): Setting Up a Learning Environment
Sets up a PostgreSQL learning environment with Docker Compose, configures database options through an .env file, and persists data with a volume. It covers connecting with pgAdmin and basic operations inside the container, including creating a table, querying tables, and inserting data.
Using the Elasticsearch Java API
Starting with the Search API request structure and Query DSL, this article explains how to organize Elasticsearch query conditions, sorting, returned fields, and pagination. Examples show how to convert DSL into Java API calls and enable request logging for debugging.
Using Log4j2 (Part 2): Changing Log Levels at Runtime
Two ways to adjust Log4j2 log levels without restarting an application: changing the configuration through JMX in JConsole, or calling the programmatic configuration API through an HTTP endpoint. A production troubleshooting scenario illustrates when each approach is useful.
Generating PEM CA Certificates for ELK, Enabling HTTPS, and Connecting with the Elasticsearch Java Client
Using ELK 8.2 as an example, this post walks through generating a CA certificate, configuring TLS for internode communication and HTTPS at the HTTP layer, and configuring certificates for Kibana, Logstash, and the Java client. It also covers the differences between the PEM and PKCS#12 formats and the related JDK compatibility issues.
Using Log4j2 (Part 1)
This post sorts out Log4j2's architecture and the responsibilities of each component, using UML class diagrams to explain how the configuration fits together. Through examples, it covers log output and rollover policies, uncaught exception handling, bridges from other logging frameworks, and how to enable and verify asynchronous logging.
Notes from Reading the Docker Documentation
Notes on Docker’s getting-started tutorial cover building images, starting containers, persisting data, and composing multi-container applications. Topics include RUN versus CMD in Dockerfiles, named volumes and bind mounts, Docker Compose, and basic Docker Desktop operations.
Getting Started with JMX: JMX Exporter Monitoring and OpenTelemetry Integration
Demonstrates JMX registration, attribute queries, and JConsole operations with a custom MXBean, then introduces metrics collection through JMX Exporter, OpenTelemetry Collector, and Prometheus. It also discusses MBean filtering and scrape performance, and OpenTelemetry JMX integration options.
Sending Email with Velocity in Spring Boot
Velocity references, directives, variable assignment, and resource loading are introduced through rendering order emails in Spring Boot. JavaMailSender and SMTP configuration for a 163.com mailbox demonstrate building, sending, and verifying HTML email.
Getting Started with React (Part 2): Sending Requests and Mocking Data
Integrating Axios into a React login form, this article centralizes the request instance, wraps API calls, and uses promises to handle responses and end the submission state. It serializes form data with qs, mocks responses with Mock.js, and verifies the interaction through console output and loading animations.
Using Formik for React Forms and Yup for Frontend Validation
Uses a React signup form to introduce Formik initial values, submission handling, and form validation, with touched and onBlur controlling error messages. It then uses Yup to define validation rules and getFieldProps to simplify binding input components to form state.
Getting Started with React (Part 1): Building a Basic Application
Starting with Node.js environment setup, this article manually builds a basic React application with Babel, Webpack, an HTML entry point, components, and styles. It demonstrates the development server, hot updates, and bundling, and provides the project structure and example repository.
Implementing the OAuth 2.0 Authorization Code Flow
A custom OAuth 2.0 authorization code implementation using RESTEasy, JPA, CDI, and JWT connects user consent, code generation, callbacks, and token exchange. The article shows signature and permission checks on the resource server, along with the project structure, deployment steps, and complete example code.
Getting Started with RESTEasy
Starting from Servlet and JAX-RS specifications, this post introduces RESTEasy Applications, Resources, and Providers and explains initialization in a Servlet container. Examples cover HTTP requests, forms, file transfers, and global exception responses.
Getting Started with JWT and nimbus-jose-jwt
JWT structure, common claims, and the purpose of signatures are introduced with HMAC and RSA signing and verification examples using nimbus-jose-jwt. JWE content encryption then illustrates the distinction between signing and encryption and the roles of RSA public and private keys in different scenarios.
Reading the Java EE Official Documentation
Reading notes on the official Java EE 8 documentation, organizing concepts such as components and containers, JSF, CDI, EJB, JPA, and security, along with common terminology. The article gathers related chapters and example resources, and records Tomcat issues on Windows as well as thoughts on choosing between POST and PUT in RESTful services.
Basic Ehcache Usage
A simple Spring Boot application demonstrates programmatic and XML configuration in Ehcache 3, including cache types, expiry policies, resource tiers, and event listeners. API calls verify cache reads, writes, and expiry events, and a configuration property switches between the two initialization approaches.
SpEL: Getting Started and Quick Reference
This quick reference covers common ways to read and assign values with Spring Expression Language (SpEL), the two @Value syntaxes, and the role of the evaluation context. Java examples demonstrate property access, collection operations, method calls, null handling, and collection filtering.
Getting Started with Java RMI
Introduces the basic idea of invoking remote methods across JVMs with Java RMI, connecting the remote interface, its implementation, the registry, and client lookup and invocation. It provides two ways to find a remote service and discusses client proxies and serialization of returned objects.
Getting Started with Lua Scripts, with Example Code
A guide to Lua comments, variable scope, common data types, conditional expressions, arrays, and loops, with short examples of strings and functions. It also demonstrates calling Redis commands from Lua and provides references for the standard library and debugging tools.
Getting Started with Java EE: An Example Application
A Java EE 8 example walks through installing, starting, and configuring GlassFish 5 and H2. It demonstrates creating a JDBC connection pool and JNDI data source on the server, deploying the application from IntelliJ IDEA, and checking configuration through logs and application pages.
Practical Elasticsearch: Common Operations, Logstash Integration, Local IP Handling, and ECS Field Mapping
After the previous two blog posts, we now have article data and can query it. The next step is to keep building on that foundation.
Querying Elasticsearch
This article focuses on data queries, an important part of working with Elasticsearch.
Setting Up ELK and Getting Started
Installing Elasticsearch, Logstash, and Kibana and getting started with the basics.
Learning RabbitMQ and Spring AMQP (Part 5): Delayed Queues
Uses scenarios such as scheduled assignment publication to explain delayed messages and implements them with the RabbitMQ delayed-message plugin. It demonstrates plugin installation, declaring a delayed exchange, and setting message delays, compares Java Client and Spring AMQP code, and verifies the result through send and receive times.
Creating a Custom Spring Boot Starter
A custom framework illustrates a Spring Boot Starter’s project structure, property binding, conditional auto-configuration, and registration through spring.factories. The article demonstrates auto-configuration tests, dependency inclusion, practical usage, and overriding the framework’s default implementation with custom configuration.
Learning and Understanding Maven in Depth
Build a thorough understanding of Maven, with practical scenarios that explain plugin configuration and reduce repeated searches for how to configure Maven plugins.
Learning RabbitMQ and Spring AMQP (Part 4): JSON Message Bodies
Explains how to pass Java objects as JSON in RabbitMQ and Spring AMQP by configuring message converters on the producer and consumer. Examples cover object serialization, Content-Type and timestamp settings, and mapping received messages to Java entities with @Payload.
RabbitMQ and Spring AMQP (Part 3): Message Reliability
Message delivery, storage, and consumption introduce publisher confirms, returned messages, durable components, and message persistence in Spring AMQP. The article demonstrates manual consumer acknowledgments, rejection, and requeuing, and explains why persistence can still leave a risk of message loss.
Learning RabbitMQ and Spring AMQP (Part 2): Messaging Models and the Startup Process
Explains RabbitMQ brokers, connections, and channels, comparing the native Java client with Spring AMQP. It covers producer and consumer configuration responsibilities and pooled channel reuse, then traces listener registration, component declarations, and consumer startup through the source code.
Learning RabbitMQ and Spring AMQP (Part 1)
This article explains how producers, exchanges, routing keys, bindings, and queues relate in RabbitMQ and demonstrates virtual-host configuration and publishing from the management console. Spring AMQP examples connect exchange declarations, queue bindings, consumer listeners, and producer publishing into a basic workflow.
JVM Notes (Part 2)
A collection of common JVM diagnostic tools: use jps to obtain Java process IDs, jinfo to inspect or adjust runtime options, and jmap to view heap information. The article also introduces graphical tools such as jvisualvm and jconsole and explains how to connect to a local or remote JVM to inspect its options.
JVM Notes (Part 1)
Notes on Java bytecode, stack frames, and JVM runtime data areas, together with common startup options for heap memory, thread stacks, garbage collection, and heap dumps. Parameter conversions and capacity examples illustrate memory configuration, followed by the difference between memory leaks and running out of memory.
Arthas
This article records Arthas startup, reconnection, and common startup issues, with practical examples of finding classes, decompiling, compiling, and hot updates. It also covers changing log levels dynamically, inspecting and modifying JVM options, and cautions when using redefine.
Locks in Java (Part 3): Implementing Wait and Notify with Condition
Explains how to combine Lock and Condition to make threads wait and notify one another, comparing await, signal, and signalAll with wait/notify. A ReentrantLock example illustrates thread coordination and the requirement to acquire the lock before waiting or notifying and release it afterward.
Locks in Java (Part 2): Implementing a Custom Lock
Introduces lock memory semantics and the use of AQS and the Lock interface to implement custom synchronization components, including an example that allows two concurrent threads. It also compares polling with wait/notify and discusses notification, competing for a lock again, and checking conditions.
Locks in Java (Part 1): Lock Categories
Focusing on the object header’s Mark Word, this article explains acquisition, contention, release, and promotion of biased, lightweight, and heavyweight locks. JOL examples inspect lock flags before and after synchronized code, followed by discussion of spinning, blocking, and suitable use cases.
Computer Networks: The Data Link Layer
An introduction to data-link frames, the maximum transmission unit, byte stuffing, and CRC error detection, followed by the role of network cards and MAC addresses. The article describes transmission and collision detection on broadcast channels and gathers related notes on modems, optical fiber, and switches.
Computer Networks: The Transport Layer
Starting from ports and inter-process communication, this article introduces TCP's byte-stream transmission, automatic retransmission, sliding window, and segment structure. It uses Wireshark packet captures to analyze the three-way handshake and the four-way termination, and discusses connection states such as TIME-WAIT and CLOSE-WAIT together with related troubleshooting scenarios.
Computer Networking: The Network Layer
Reviews IPv4 address classes, ARP address resolution, IP datagrams, subnet masks, and routing, and explains the relationship between IP and MAC addresses. It also records troubleshooting connection failures after rebuilding AWS VPC instances and the solution of retaining network interfaces.
Computer Buses and Memory
This article outlines bus architectures and the roles of data, address, and control buses, with examples of bus width and bandwidth. It also describes main memory, cache, and secondary storage and explains memory reads and writes using MAR and MDR.
A Few Things to Know About Computer Organization
This article introduces the five major hardware components and common CPU and memory registers, then uses addition to explain instruction fetch, decoding, and execution. It also demonstrates main-memory capacity calculations using address width, word length, and unit conversion.
Analyzing the ShardingJDBC Execution Flow
Uses the MyBatis call flow to analyze how ShardingJDBC 4.1.1 integrates with JDBC through custom DataSource, Connection, and PreparedStatement implementations. It traces parameter buffering, physical connection acquisition, and result-set handling, then simulates the proxy workflow with simplified code.
Getting Started with Redis (Part 4): Monitoring and Automatic Recovery with Sentinel
Redis Sentinel configuration and logs illustrate monitoring and automatic failover, including subjective and objective down states, leader election, and selection of a new primary. The article also shows replica promotion and replication changes, and discusses deploying multiple Sentinels and configuring voting thresholds.
Getting Started with Redis (Part 3): Primary/Replica Replication
This article covers Redis RDB and AOF persistence configuration and recovery, then demonstrates primary/replica replication. It explains full, incremental, and diskless replication and describes manually promoting a replica and updating replication relationships after a primary failure.
Getting Started with Redis (Part 2): Basic Data Types and Commands
Basic usage of the Redis server and client, with common commands for strings, hashes, lists, sets, and sorted sets illustrated through examples of key and data operations. The article also distinguishes the atomicity of individual commands from that of an entire business workflow, and discusses the role of Lua scripts.
Integrating GitHub with CircleCI, with a Sample Configuration
Connecting a GitHub project to CircleCI, with a config.yml example explaining workflows, jobs, and execution steps. Topics include Maven builds, dependency caching, saving test results, branch filtering, scheduled builds, and verification that the configuration takes effect.
Using ShardingSphere Database Middleware: ShardingProxy (Part 1), Data Sharding and Read/Write Splitting
Uses ShardingProxy 4.1.1 to configure data sharding and read/write splitting across multiple MySQL instances, then verifies routing through query and insert logs. It covers starting the proxy service, connecting an application, and MySQL driver and version compatibility considerations.
Using Solr (Part 5): A Complete Command-Line Workflow and HTML Tag Filtering
Command-line and curl examples demonstrate a complete Solr workflow: managing cores and fields, CRUD operations, pagination, and conditional queries. The article also configures HTML tag filtering for rich-text searches and explains copyField and fieldType.
ShardingSphere (Part 4): Custom Encryption Strategies for Data Masking
Using ShardingSphere 4.1.1, this article implements and configures custom encryption strategies and traces SPI-based encryptor registration through the source code. It demonstrates Encryptor and QueryAssistedEncryptor separately, then verifies how an assisted-query column supports queries over differing ciphertext values.
Git Basics and Contributing Pull Requests to Open-Source Projects: Practical Troubleshooting
This article answers common GitHub workflow questions: dealing with slow or failed clones, keeping a fork synchronized with upstream, submitting pull requests, and handling other practical Git issues.
Getting Started with SkyWalking
Introduces installation, configuration, and startup of SkyWalking and Elasticsearch, then configures agents for Spring Cloud microservices. Dashboards, topology, and tracing views illustrate individual services, service-to-service calls, and database access, including how to inspect SQL and its parameters in a trace.
Custom YAML Configuration in Spring Boot
How can you define your own Spring Boot YAML configuration, and what conventions should you follow? This article shares the approach I developed through hands-on practice.
Using ShardingSphere–ShardingJDBC (Part 3): Data Masking
Building on data sharding and read/write splitting, this article uses ShardingJDBC’s built-in algorithms to encrypt stored fields and decrypt query results. It verifies the configuration through inserts and queries and discusses full routing without a sharding key, including the number of tables queried and the maintainers’ explanation.
Using ShardingSphere Database Middleware: ShardingJDBC (Part 2), Read/Write Splitting
Builds on a data-sharding example to configure ShardingJDBC read/write splitting for a MySQL primary-replica setup. It introduces primary and replica data sources and replica load-balancing strategies, observes queries alternating between replicas, and records the unresolved issue of a slow first query.
Using ShardingSphere–ShardingJDBC (Part 1): Data Sharding
An introduction to data sharding in ShardingSphere–ShardingJDBC, with database and table sharding demonstrated across two MySQL instances. An example selects databases by id and tables by age to observe write and query routing, and explains how sharding keys relate to full routing.
Understanding Spring IoC
An exploration of Spring IoC through bean creation and dependency injection, including constructors, factory methods, and setters. The article also traces component scanning in the source code to see how annotated classes become bean definitions and how the container manages objects and their dependencies.
How Does Spring Perform Property Injection?
Analyzes Spring’s setter and constructor injection workflows through the dependency between two beans. By tracing property resolution and getBean calls, it explains how existing dependencies are reused and missing dependencies are created, and compares when the two injection methods run.
When Does Spring Instantiate Beans?
Starting from XML configuration, this article uses source-code debugging to examine bean definition registration, object creation, property population, and initialization in Spring. It explains how BeanFactory stores the relevant information and compares when non-lazy singleton and prototype beans are created during container startup or actual use.
Using Solr (Part 4): Spring Data Solr in Real Applications, with Practical Code Examples
Uses practical examples to introduce Spring Data Solr configuration, entity mapping, CRUD, and pagination, and demonstrates queries using @Query and SolrTemplate. It also discusses extending custom repositories, using transactions, and checking query statements through logging.
Using Solr (Part 3): SolrJ in an Application
Java examples introduce SolrJ dependency configuration, entities annotated with Field, and a shared SolrClient wrapper. The article demonstrates adding, updating, deleting, and querying data, verifies the results in the Solr console, and explains why the core must be specified when committing.
Using Solr (Part 2): Full and Incremental Imports from MySQL
Explains how to configure Solr DataImportHandler for full and incremental imports from MySQL and periodically refresh data with operating-system scheduled jobs. It also covers tinyint fields, multivalued fields, and Transformers, and outlines DIH components and changes in later versions.
Using Solr (Part 1): Installation, Core Management, Queries, and Fixing CoreContainer Initialization Errors
Introduces Solr installation and startup, custom cores and field configuration, and demonstrates adding, querying, and deleting data through the console and curl. It also covers stopping Solr, deleting cores, and checking the core name when copied configuration causes a CoreContainer initialization failure.
Using Git Rebase
Uses a branch merge that requires combining multiple commits to introduce interactive Git rebase and commit-message editing. It compares squash, fixup, commit --amend, and resetting followed by a new commit, and explains how to abort an unfinished rebase.
Using Docker: Network Configuration
Examples of communication between containers compare Docker’s default network, links, and a custom bridge network. The article shows how to inspect container IP addresses and network details, and how a custom network lets containers reach one another by name without depending on specific IP addresses.
Distributed Transactions with Seata: Installing Seata Server and Using AT Mode
A rollback problem involving calls between Spring Cloud microservices introduces Seata Server installation, database storage configuration, and Eureka registration. AT mode, the undo_log table, and a global transaction annotation are then used to verify rollback after an exception in a cross-service call.
MySQL Primary-Replica Replication: Detailed Setup and Troubleshooting Replicas That Stop Synchronizing
Sets up primary-replica replication using multiple local MySQL instances and introduces replication threads, binlog formats, and configuration steps. Based on actual errors, it covers authentication failures and replicas that stop synchronizing, and discusses asynchronous and semisynchronous replication and common replication topologies.
Using Docker: Building a CentOS Image with Java and Maven
Using Docker on macOS, this article records building a CentOS image with a Dockerfile and configuring Java and Maven. It also covers container users, running a Java application, and saving, tagging, pushing, and pulling the custom image.
Migrating SQL Server Data to MySQL: Connection Troubleshooting and Bulk Imports
This article records a SQL Server-to-MySQL migration with Navicat and troubleshooting when the server refuses connections. It also covers MySQL file imports and exports, directory permissions, delimiters, duplicate handling, and default field values during bulk imports.
Relearning MyBatis (Part 5)
Analyzes how MyBatis getMapper uses JDK dynamic proxies to create proxy objects for Mapper interfaces. By tracing MapperProxy, MapperMethod, and SqlSession calls, it explains how Mapper methods become SQL operations without requiring handwritten interface implementation classes.
Deploying Multiple MySQL Instances on One Mac: A Detailed Walkthrough
This article records deploying multiple MySQL instances on a Mac, compares shared and separate configuration files, and details copying an instance, initializing its data directory, and configuring ports and sockets. It also discusses directory permissions, startup, and Navicat connection problems.
Relearning MyBatis (Part 4): JDK Dynamic Proxies in Detail
This article revisits the proxy pattern and JDK dynamic-proxy source code to clarify interfaces, implementation classes, proxy classes, and InvocationHandler. Two usage examples explain proxy generation and method invocation, with connections to Spring AOP and MyBatis.
Relearning MyBatis (Part 3)
Source-code debugging traces how MyBatis loads configuration and Mapper XML, and turns SQL statements and their attributes into MappedStatement objects. The article follows placeholder conversion, SqlSource creation, and registration of statement information in the global Configuration.
Relearning MyBatis (Part 2)
Continuing the MyBatis insert flow, this article analyzes PreparedStatement creation and SQL parameter binding. It explains the relationship among BoundSql, parameter mappings, and TypeHandler, showing how values are assigned by type and how these steps correspond to traditional JDBC.
Relearning MyBatis (Part 1)
Starting with traditional JDBC operations and MyBatis XML configuration, this article traces an insert request. Source-level debugging reveals the calls among SqlSession, executors, and StatementHandler, including obtaining a database connection, preparing a statement, and executing SQL.
Notes from a Debugging Session
Records a debugging session involving a Spring Cloud microservice calling a Word-to-image service, covering callbacks blocked by the gateway, file-processing timeouts, and incorrect image order. The workflow is improved by updating the allowlist, using input streams directly, and sorting by numeric filename prefixes.
A DNS Issue in a Development Environment
During API acceptance testing, the development environment kept returning 502 errors even though the deployment team found no problem with the environment. The browser console showed that the domain resolved to the wrong IP address, so I changed my local DNS server settings.
Where to Put Filter Conditions in MySQL Joins
A two-table LEFT JOIN example compares the results of putting filter conditions in ON versus WHERE. It shows how a condition on the right-hand table in WHERE removes some left-hand records, and how moving the condition changes the join results to match the intended output.
Spring Boot: Pitfalls with @Async and @Transactional
Using asynchronous conversion of uploaded Word documents to images as an example, this article investigates why @Async did not take effect in Spring Boot. It explains the importance of return types and calls through a proxy, and discusses similar considerations for @Transactional when methods call other methods in the same class.
Using Shiro: Complete Spring Boot Integration Code
The main code for integrating Shiro, Spring Boot, and JWT: the Shiro configuration, a custom Realm, an authentication filter, and a JWT utility. Together, these four pieces show login authentication, request interception, and token creation and validation, with a look back at the session-management choices made during integration.
Using Shiro: Integrating JWT for More Capable Tokens
JWT is integrated with Shiro and Spring Boot to issue tokens after login and parse, validate, and check them for expiry on subsequent requests. This article explains the JWT utility, authentication filter, and configuration properties, and traces a dependency-injection failure caused by constructing the filter manually.
Using Shiro with Tokens
A custom Shiro filter validates tokens on incoming requests. The article covers returning a token after login, adding the filter to the authentication chain, and tracing filter execution order in the source code, then discusses token expiry and distributed authentication that the example has not yet implemented.
Using Shiro: A Primer on Tokens and Why to Use Them
Starting from login validation in traditional web applications, this article discusses the differences between sessions and tokens in storage, sharing across distributed systems, and request authentication. It compares validation approaches using a database, Redis, or no token storage to clarify design considerations for implementing token authentication with Shiro.
Using Shiro: Password Hashing and Salting, with Authentication Troubleshooting
This article walks through password hashing, salted storage, and login verification in Shiro and uses its source code to explain credential comparison. It also covers troubleshooting passwords still stored as plaintext and authentication failures after salting, including the roles of the algorithm, salt, and hash iteration count.
Using Shiro: Basic Session Management
This article covers Shiro session management, including session ID generation, cookie storage, SessionDAO, and expired-session cleanup. It also describes periodic validation with Quartz and disabling session ID URL rewriting to avoid exposing IDs after redirects.
Learning Linux (Part 2)
Two practical Linux command examples: using find with xargs or exec to locate and remove lastUpdated files left by failed Maven downloads, and using less to page through files too large to fit on one screen.
MyBatis Generator: Configuration and Usage Notes
This article adds practical notes on configuring and running MyBatis Generator, including output directories, database connections, and a custom generic Mapper. It discusses configuration file paths, the resources directory name, and details to check when running generation from IntelliJ IDEA.
Using Shiro Remember Me and Automatic Login: Fixing a deleteMe Cookie
Introduces Shiro rememberMe configuration and automatic login on a later visit, and records a source-code investigation of cookies containing deleteMe. Making the User object used in authentication implement Serializable resolves the serialization failure that breaks the remember-me feature.
Using Shiro: A Basic Login Flow
This article introduces a basic login flow with Shiro and Spring MVC, including filter configuration, authentication in a custom Realm, and redirects after successful login. Missing accounts, incorrect passwords, and locked accounts illustrate authentication-code and login-URL configuration considerations.
Installing Homebrew on macOS, with Troubleshooting Tips
A record of installing Homebrew on macOS, switching mirrors, and troubleshooting installation errors, followed by common questions about brew tap, pinning versions, and disabling updates. The article notes changes to the old installation script and adds mirror installation documentation.
Java Primitive Types and Wrapper Classes
Using entity properties and database null handling as examples, this article discusses the differences between Java primitive types and wrapper classes, particularly when double, int, and their wrappers encounter null values.
Uploading Images with Spring MVC
A simple Spring MVC image-upload example covering form settings, receiving and saving files, multipart resolver configuration, and dependencies. It also describes using a MultipartFile array for multiple images, with validation left for further development.
Configuring the Home Page of a Web Project
Troubleshooting home-page navigation to a JSP under WEB-INF, followed by an update that adjusts the DispatcherServlet mapping and the controller’s root mapping. It also covers issues with component scanning, listeners, and static resource configuration.
Spring in Development (Part 1)
Starting from a save operation that runs without writing data to the database, this post checks how method names match Spring transaction configuration. It explains REQUIRED and SUPPORTS, then covers the remaining propagation settings and their relationship to transaction rollback.
Lessons from Using Spring MVC at Work (Part 2)
Troubleshooting a 404 when returning a JSP view from another directory in Spring MVC. It compares specifying a view with ModelAndView and making a new request with redirect, and explains why .jsp should be omitted when the view resolver already supplies the suffix.
Learning Linux (Part 1)
Introductory Linux notes covering common directories under the root filesystem, directory navigation, archive creation and extraction, command-line shortcuts, file listings and permissions, and checking file sizes.
Java Development Details (Part 3)
Two basic Java techniques illustrated with development examples: using a string’s length to calculate the starting index for extracting a fixed-length suffix with substring, and using a labeled break to exit an outer loop.
Using Docker (Part 2)
A basic Docker workflow using a CentOS image: obtaining an image, creating and leaving a container, committing changes, tagging the image, and pushing it to a remote repository. It also covers login issues and commands for removing containers and images.
Using jQuery zTree
Notes on displaying backend data as a tree with jQuery zTree, including the HTML node, setting options, and zNodes data used for initialization. It also links to the official API and a reference on building tree data from database queries.
A Painful Web Project Deployment on a Mac
A troubleshooting account of deploying a web project on a Mac with Eclipse, Tomcat 7, and JDK 7. It covers compiler versions, Servlet dependencies, IPv4 settings, and JVM options, with particular attention to repeated deployments and duplicate JAR files.
Installing and Using Docker (Part 1)
Notes on installing and initially configuring Docker on a Mac: downloading the client, checking the installation from the terminal, and setting up an Alibaba Cloud registry mirror for use in China. It also covers checking settings after client upgrades and a problem encountered when configuring the mirror URL.
Learning About Asynchronous Ajax Requests in Web Applications (Part 2)
A troubleshooting account of an Ajax request that returns a successful HTTP status but enters the error callback. It uses response details to identify a JSON parsing problem and checks @ResponseBody, then covers a case where code reads variables before an asynchronous request finishes and gets undefined.
Building a Maven Project with IntelliJ IDEA (Part 1)
Steps for building a simple web project with Maven and IntelliJ IDEA on a Mac, with references for installation and IDE setup. It also explains how configuring a Maven mirror can address slow dependency downloads and lengthy builds.
Understanding Spring MVC through a Request-Mapping Error
Starting with a controller-to-URL mapping error, this article traces Spring MVC’s request-processing flow. It explains the collaboration between DispatcherServlet, HandlerMapping, HandlerAdapter, and ViewResolver, including how the view and data are returned.
Observations on ArrayList Capacity Growth
This article records an ArrayList debugging experience involving capacity and apparent null entries. It discusses initial capacity, automatic growth, and the value of specifying capacity when the expected collection size is known.
Java Development Details (Part 2): Configuration Mistakes
This article records three configuration mistakes: an incomplete quote around a MyBatis XML id, duplicate Spring MVC controller names, and a misspelled resultMap name. Error messages and troubleshooting steps illustrate why careful configuration checks matter.
Dealing with Sluggish Development Tools
Links to approaches for improving responsiveness in MyEclipse and IntelliJ IDEA.
Troubleshooting “split is not function”
An attempt to split a frontend value with JavaScript produced a “split is not function” error. Converting the value with toString() resolved it, although the underlying cause had not yet been investigated.
Troubleshooting Duplicate Rows in Database Query Results
This article investigates duplicate results from multi-table left joins without discarding legitimately identical business records. It describes using Oracle ROWID for deduplication, assigning column aliases, and converting ROWID with ROWIDTOCHAR for Java object mapping.
Understanding Ajax’s async Option
This article investigates why an Ajax request returns data while the calling function returns undefined. It explains the order of callback assignment and function return in an asynchronous request, using a MiniUI example to illustrate the async setting.
Substring Searches over Large Datasets
A suggestion to use MySQL’s LOCATE function.
Handling Blank Rows When Importing Excel with Apache POI
This article explains how deleting an entire Excel row differs from clearing its contents when importing with Apache POI. It describes checking rows, cells, and cell types to exclude empty rows and prevent empty data from being written to the database.
Oracle Window Functions
A detailed introduction to Oracle window functions.
Problems Caused by Deleting Oracle Tablespace Files Directly
This article recounts troubleshooting ORA-01109 and ORA-12514 after deleting Oracle tablespace files directly. It records database startup, SYSDBA login, and listener configuration issues, and concludes that tablespaces should be removed through the normal deletion procedure.
Useful Blog Posts about Network Frames
These should be available in my bookmarks.
Getting Started with Redis (Part 1): Basic Setup on Windows
This article records basic Redis operations on Windows: connecting with redis-cli, setting requirepass and authenticating with AUTH, writing data with SET, and setting key expiration in seconds or milliseconds.
Web Development Notes (Part 1): IP Addresses, Ports, and JVM Memory
This article collects environment troubleshooting steps for web development: finding a Windows machine’s IP address and occupied ports, accessing a local project by IP, and adjusting Tomcat-related JVM memory settings in MyEclipse and IntelliJ IDEA.
Java Development Details (Part 1)
This article collects Java fundamentals that are easy to overlook: two-dimensional arrays, string concatenation and character arrays, integer parsing and numeric ranges, digit conversion, and split parameters. Examples highlight type and boundary issues encountered in practice.
Small Details to Remember in Everyday Development
A few development reminders: log caught exceptions with a logger; consider entrySet when iterating over a map; and, when using indexof, prefer single-quoted characters over double-quoted strings.
Everyday Development Pitfalls
This article collects easily overlooked development details: avoiding null-pointer errors in string comparisons, declaring generic collections, concatenating Oracle strings, and using IS NULL or IS NOT NULL in SQL.
Oracle IN and EXISTS: Query Notes
This article compares IN and EXISTS through practical Oracle query issues, emphasizing the need to correlate an EXISTS subquery with the outer table. It also records considerations involving NULL, NOT IN, and execution plans.
JavaScript Error Notes (Part 1)
This article collects several JavaScript issues: converting numbers to strings before calling split, formatting numbers with thousands separators using replace and a regular expression, and setting focus on an input with jQuery.
Notes on Java’s static Keyword
Using static methods for querying approval documents as an example, this article records observations about static members, direct method calls, and loading order. It also discusses questions about invocation frequency and memory use in business queries.
Oracle Query Notes (Part 2): INSTR, LPAD, and RPAD
This article introduces Oracle’s INSTR function through examples of its parameters, return values, and use in WHERE conditions. It then explains the padding directions of LPAD and RPAD, using a sequence value padded with zeros as an example.
Thoughts on Improving Database Query Performance
This article considers slow queries on large tables from three angles: SQL quality, table and index design, and table partitioning. These are preliminary ideas; the partitioning approach has not yet been put into practice.
Interesting Thoughts on Frontend and Backend Engineering
This article collects other bloggers’ views on frontend and backend engineering skills. It outlines learning areas for each role, from Java, databases, and distributed systems to browsers and build tools, along with their respective performance and user-experience goals.
Troubleshooting Oracle Connection Errors
This article records a PL/SQL connection failure involving TNS errors. It covers checking connectivity with tnsping, adjusting HOST settings, restarting the listener, testing login with SQL*Plus, and configuring the Oracle home used by PL/SQL.
Static and Dynamic Includes in JSP
This article compares static and dynamic JSP includes by considering whether the pages share a single servlet. Examples involving page encoding, duplicate variables, and generated class files illustrate the practical differences.
Getting Started with Ajax in Web Applications (Part 1)
Using search suggestions as an example, this article explains how Ajax communicates with a server without reloading the page. It introduces common jQuery request options and traces XMLHttpRequest creation, request sending, and response-state handling.
Java String Comparisons: equals and ==
This article recounts a failed condition caused by using == to compare a value received from JSP with a server-side string. It uses the incident to explain the difference between comparing string contents and comparing object references in Java.
Java Character Encoding and Decoding (Part 2): URL Encoding
This article traces URL encoding and decoding in Java through URLEncoder, URLDecoder, and Charset lookup. It explains hexadecimal byte representation in percent-encoded URLs and briefly introduces chunked transfer through examples of request and response headers.
Java Character Encoding and Decoding (Part 1)
Using String.getBytes as an example, this article traces how Java looks up a character set, creates an encoder, and converts a string to a byte array. It also outlines the similar process used to decode bytes into characters.