Hanxinhu'Blog

人人都是架构师 读书笔记

2019-05-27

#人人都是架构师

服务器的目标:

高性能 高可用 易扩展 可伸缩 相对安全

架构演变过程:

单机架构 > 机群架构 > 分布式架构

演变过程中外围系统和存储系统的改变:

关系型数据库的分库分表改造

从本地缓存过渡到分布式缓存

技术的目的

任何技术的初衷都是为了更好的服务业务 一旦脱离业务 技术必然会失去原有的价值和意义

单机系统

文件服务器、web服务器、数据库全都在一个物理服务器上

  • 独立部署 避免不同的系统之间相互争夺共享资源
  • Web服务器集群 实现可伸缩性
  • 部署分布式缓存系统 使得查询尽可能命中在缓存中
  • 数据库实施读写分离 实现HA high availability 架构

集群架构

优势:

提升业务系统的并行处理能力、降低单机系统负载、以便支撑更多的用户访问操作。

一个基本共识 :
当一台服务器的处理能力接近或者已超出其容量上限时,不要企图用一台更强劲的服务器,通常采用集群技术,通过增加新的服务器来分散并发访问量

无状态的Web节点可以通过Nginx来实现负载均衡调度

集群环境中Web节点的数量越多 并行处理能力就越强,哪怕某些节点宕机,也不会使得整体不可用。

可行的操作:

利用CDN( content deliver network ) 加速系统响应
业务垂直化、降低耦合、分而治之的管理

以业务功能为维度拆分出多个子系统,规划和体现出每个子系统的职责,降低业务耦合,提升容错率

系统服务化需求

RPC remote procedure call 远程过程调用

三个步骤 RPC封装下面的底层处理细节

  • 底层的网络通信协议处理

  • 解决寻址问题

  • 请求/响应过程中参数的序列化和反序列化工作

Dubbo

Provider先向注册中心注册指定的服务,这样作为服务调用方的Consumer在启动后便可以向注册中心订阅目标服务,然后在本地根据负载均衡算法从地址列表中选择其中一个服务节点进行RPC调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package org.apache.dubbo.samples.api;

public interface GreetingService {
String sayHello(String name);
}
package org.apache.dubbo.samples.provider;

import org.apache.dubbo.samples.api.GreetingService;

public class GreetingServiceImpl implements GreetingService {
@Override
public String sayHello(String name) {
return "Hello " + name;
}
}
package org.apache.dubbo.demo.provider;

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.samples.api.GreetingService;

import java.io.IOException;

public class Application {

public static void main(String[] args) throws IOException {
ServiceConfig<GreetingService> serviceConfig = new ServiceConfig<GreetingService>();
serviceConfig.setApplication(new ApplicationConfig("first-dubbo-provider"));
serviceConfig.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
serviceConfig.setInterface(GreetingService.class);
serviceConfig.setRef(new GreetingServiceImpl());
serviceConfig.export();
System.in.read();
}
}
package org.apache.dubbo.demo.consumer;

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.samples.api.GreetingService;

public class Application {
public static void main(String[] args) {
ReferenceConfig<GreetingService> referenceConfig = new ReferenceConfig<GreetingService>();
referenceConfig.setApplication(new ApplicationConfig("first-dubbo-consumer"));
referenceConfig.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
referenceConfig.setInterface(GreetingService.class);
GreetingService greetingService = referenceConfig.get();
System.out.println(greetingService.sayHello("world"));
}
}

RPC调用失败后可选的操作:

failover 调用失败 重试其他节点 通常用于读操作
Failfast 只发起一次调用,失败立即报错,通常用于非幂等性的写操作

什么是幂等性
HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

Failsafe 失败安全,出现异常时直接忽略 用于写入审计日志等操作
Failback 失败自动恢复 后台记录失败请求,定时重发,通常用于消息通知操作
Forking 并行调用多个服务节点,成功1个即返回,通常用于实时性较高的读操作

服务治理

  • 服务的动态注册与发现
  • 服务的扩容评级
  • 服务的升降级处理

监控中心: 更好地掌握服务的状态信息
引入注册: 实现服务的动态注册和发现,服务将得到解脱,在客户端实现负载均衡和Failover将会大大降低对硬件负载均衡器的依赖。

特殊情境下,可以对次要服务进行降级,牺牲部分功能保证系统的核心服务不受影响。

难题 :分布式事务
只要保证最终一致性,数据短暂不一致的窗口期也无妨
重点是解决主要矛盾
JVM调优 吞吐量和低延迟相互矛盾
吞吐量有先,GC花费更长的暂停时间来执行内存回收。
反之,频繁地内存呢回收导致吞吐量下降。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章