1. Focus on the benefit instead of the technology
It is useless when using technology because of the technology. We need to focus on the benefit that technology provides.
- If it can reduce the technical complexity and speed up the development process for the team
- If it can make the system more reliable
- If it can simplify and automate to reduce cost
2. Design from a service/API perspective instead of resource or technology
Design from service/API establishes a top-down approach. This helps to distribute the vision to a wider team and enables collective system improvement over time instead of fragmented.
3. Use mainstream and mature technology
- Technology needs to be selected wisely so that less effort needs to spend on evolving.
- Use more mature technology instead of technology just because you know it.
- Don’t reinvent the wheel.
All the self-invented wheels or non-popular technologies will eventually get replaced by mature open source software, as they have huge support on new features and reliability patches.
4. Favour the completeness over performance
Use concise (ACID) technology as main architecture, and non-ACID technology as additional service
Performance issues can have many solutions but incorrect data won’t get fixed until you rearchitect the solution
5. Follow the standard and best practice
This includes many conventions:
- Service agreement: restful API path, HTTP method, Header, Json schema
- Naming convention: userID, serviceID, tag name, status, error code
- Logging and monitoring: logging format, data monitoring, alarm system
- Configuration: system configuration, middleware, software package
- Middleware: software, caching, message queue
- Software and package: unify across the teams, e.g. at least once a year, perform a corporate-wide software update, this helps in simplifying the overall system complexity.
6. Pay attention to architecture extensibility and maintainability
Software is not once written once done, it requires continuous maintenance. In fact, 80% of costs are spent on maintenance. Thus extensibility and maintainability are important
- Use service orchestrator to reduce the coupling between service: e.g. workflow, event-driven architecture, broker, gateway, service discovery
- Follow the software design principals
7. Clear separation between business logic and control logic
The software usually involves two parts business logic and control logic. Control logic includes multiprocess vs distribute system, file vs database, and how to configure/deploy/maintain/monitor/alarm/discover/scale…
Control logic is usually complex and can cause many potential issues. It should get collectively isolated and handled by the experts
8. Don’t favor the compatibility with old systems’ debt
Old systems sometimes come with debt like:
- Outdated technology: Http1.0, Websphere, Mesos
- Bad designs: deep coupling between data and business logic, monolithic architecture
- Lack of DevOps practice: no automation, no documentation, no standard nor quality control
- Instead of spending a huge effort to make the new service backward compatible, we’d better pay back the technical debt now and reduce complexity in the future
- Do not allow debt from the old system to influence the new system
9. Rely on evidence and data instead of our own experience
10. Be careful of X-Y problem
When Solving an X problem people think Y can solve it then dig into finding how to implement Y. However, there may exist a Z solution that outperforms Y.