Software Architecture

Scalable Web Architecture

CS/BS架构挑战

实验


写个计算密集型(Compute-intensive)服务

https://www.bilibili.com/video/BV1X7411S7yM?p=1 (3:15)

sa-spring/app-pi

压力测试


Load testing is the process of putting demand on a system and measuring its response.

- https://en.wikipedia.org/wiki/Load_testing

https://www.bilibili.com/video/BV1X7411S7yM?p=1 12:50

扩展



垂直扩展(Scale Up)

用虚拟化技术模拟实现


https://docs.docker.com/install/

Containerization

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.1.0</version>
    <configuration>
        <to>
            <image>app-pi</image>
        </to>
    </configuration>
</plugin>
mvn compile jib:dockerBuild

垂直扩展实验










https://www.bilibili.com/video/BV1X7411S7yM?p=2 (20:40)

垂直 vs. 水平扩展(Scale Out)

水平扩展

负载平衡是一种计算机技术,用来在多个计算机、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载平衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务通常是由专用软件和硬件来完成。

https://zh.wikipedia.org/zh-cn/负载均衡

DNS Round Robin

  • 优点:简单
  • 缺点:难以控制(DNS刷新延迟)

L3/L4/L7 Load Balancing

L3 负载均衡



  • 优点:可控
  • 缺点:网络部署相对复杂

L4负载均衡




HAProxy

HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。 GitHub、Bitbucket、Stack Overflow、Reddit、Tumblr、Twitter和 Tuenti在内的知名网站,及亚马逊网络服务系统都使用了HAProxy。

http://www.haproxy.org/

HAProxy

  • HAProxy大量利用操作系统本身的功能特性,使得其在处理请求时能发挥极高的性能,通常情况下,HAProxy自身只占用15%的处理时间,剩余的85%都是在系统内核层完成的。
  • 作者在2009年使用1.4版本进行了一次测试,单个HAProxy进程的处理能力突破了10万请求/秒,并轻松占满了10Gbps的网络带宽。
  • 作为建议以单进程模式运行的程序,HAProxy对稳定性的要求是十分严苛的。按照作者的说法,HAProxy在十几年间从未出现过一个会导致其崩溃的BUG,HAProxy一旦成功启动,除非操作系统或硬件故障,否则就不会崩溃。
L4 实验: HAProxy(TCP mode)

https://www.bilibili.com/video/BV1X7411S7yM?p=3 (23:00)

defaults
    mode tcp
frontend lb-app-pi
    bind *:8080
    default_backend servers
backend servers
    balance roundrobin
    server server1 localhost:8081
    ...

Cache missing

Cache Server

Spring Caching

https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-caching

Caching

import org.springframework.cache.annotation.Cacheable;

  
  @Cacheable(“pi")
  public double calculatePi(double n) {
    double pi = 0;
    for (int i = 1; i < n; i++) {
      pi += Math.pow(-1, i + 1) / (2 * i - 1);
    }
    return 4 * pi;
  }

Spring Boot with Redis Cache

https://www.bilibili.com/video/BV17g4y1871A?p=1

sa-spring/spring-cache-redis

Cache Cluster

  • 使用多个存储节点
  • 数据分区/Data Partition?
    • 哈希Hash Partitioning
    • 一致性哈希Consistent Hashing

Hash Partitioning

def set(key, value, servers):
    n = len(servers)
    index = hash(key) % n
    servers[index].set(key, value)
# base case             # adding one node (3+1)     # removing one node (3-1)
>>> n = 3               >>> n = 4                   >>> n = 2
>>> hash('key1') % n    >>> hash('key1') % n        >>> hash('key1') % n
1                       2                           0
>>> hash('key2') % n    >>> hash('key2') % n        >>> hash('key2') % n
0                       1                           1

Consistent Hashing

Consistent hashing is based on mapping each object to a point on the edge of a circle (or equivalently, mapping each object to a real angle). The system maps each available machine (or other storage bucket) to many pseudo-randomly distributed points on the edge of the same circle.

https://en.wikipedia.org/wiki/Consistent_hashing

相关概念:Distributed hash table

https://en.wikipedia.org/wiki/Distributed_hash_table

Consistent Hashing

将Server标识与数据键映射到同一个值域空间

hash("server-1") = 3
hash("server-2") = 7
hash("server-3") = 11

hash("testkey-1") = 3
hash("testkey-2") = 4
hash("testkey-3") = 8
hash("testkey-4") = 12

Spring Boot with Redis Cluster

https://www.bilibili.com/video/BV17g4y1871A?p=2 14:40

Redis Cluster

自动创建

edis-5.0.8/utils/create-cluster> ./create-cluster start
redis-5.0.8/utils/create-cluster> ./create-cluster create 

https://redis.io/download#installation

Redis Cluster

手动创建

redis-server ./redis.conf

https://redis.io/topics/cluster-tutorial

Redis Slots

Spring Boot with Redis Cluster

sa-spring/spring-cache-redis-cluster

Cookies and Sessions

会话(session)是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制,session在网络协议中是非常重要的部分。在不包含会话层或者是无法长时间驻留会话层的传输协议中,会话的维持需要依靠在传输数据中的高级别程序。HTTP cookie就会被用来包含一些相关的信息,例如session ID,参数和权限信息等。

相关概念:Spring Bean Scope
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes

Session

相关概念:Spring Bean Scope
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes

Session Stickiness

https://www.haproxy.com/blog/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/

Tomcat Cluster

Session Replication
/Web Farming

Spring Session with JDBC

https://www.bilibili.com/video/BV17g4y1871A?p=3 6:40

sa-spring/spring-session-jdbc

Spring Session with Redis

https://www.bilibili.com/video/BV17g4y1871A?p=4 (0:10)

sa-spring/spring-session-redis

Scalable Web Architecture and Distributed Systems

http://aosabook.org/en/distsys.html