什么是集群
  一组通过高速网络互联的计算组,并以单一系统的模式加以管理
  将很多服务器集中在一起,提供一种服务,在客户端看来就象是只有一个服务器
  可以在付出较低成本的情况下获得在性能,可靠性,灵活性方面的相对较高的收益
  任务调度是集群系统的核心技术

集群的目的
  提高性能:计算密集应用,如天气预报,核试验模拟
  降低成本:相对百万美元的超级计算机,价格便宜
  提高可扩展性:只要增加集群节点即可
  增强可靠性:多个节点完成相同功能,避免单点失败

集群分类
  高性能计算集群HPC
    通过以集群开发的并发应用程序,解决复杂的科学问题
  负载均衡(LB)集群
    客户端负载在计算机集群中尽可能平均分摊
  高可用(HA)集群
    避免单点故障,当一个系统发生故障时,可以快速迁移

LVS项目介绍
  Linux虚拟服务器(LVS)由章文嵩读博期间创建
  LVS可以实现高可用,可伸缩的Web,Mail,Cache和Media等网络服务
  最终目的是利用linux操作系统和LVS集群软件实现一个高可用,高性能,低成本的服务器应用集群

LVS集群组成
  前端:负载均衡层
    由一台或多台负载调度器构成
  中间:服务器群组层
    有一组实际运行应用服务的服务器组成
  后端:数据共享存储层
    提供共享存储空间的存储区域

LVS术语
  Director Server:调度服务器
    将负载分发到Real Server的服务器
  Real Server:真实服务器
    真正提供应用服务的服务器
  VIP:虚拟IP地址
    公布给用户访问的虚拟IP地址
  RIP:真实IP地址
    集群节点上使用的IP地址
  DIP:调度器连接节点服务器的IP地址

LVS工作模式
  VS/NAT
    通过网络地址转换实现的虚拟服务器
    大并发访问时,调度器的性能成为瓶颈
  VS/DR
    直接使用路由技术实现虚拟服务器
    节点服务器需要配置VIP,注意MAC地址广播
  VS/TUN
    通过隧道方式实现虚拟服务器

负载均衡调度算法
  LVS目前实现10种调度算法
  常用调度算法有4种
    轮询(Round Robin) 将客户端请求平均分发到Real Server
    加权轮询(Weighted Round Robin)根据Real Server权重值进行轮询调度
    最少连接(Least Connections)选择连接数最少的服务器
    加权最少连接(Weighted Least Connections)根据Real Server权重,选择连接数最少的服务器
    源地址散列(Source Hashing)根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器

安装前准备
  LVS的IP负载均衡技术是通过IPVS模块实现的
  IPVS模块已经成为Linux组成部分

[root@localhost ~]# grep -i 'ipvs' /boot/config-2.6.-.el6.i686
# IPVS transport protocol load balancing support
# IPVS scheduler
# IPVS application helper
[root@localhost ~]# yum -y install ipvsadm

ipvsadm用法
  创建虚拟服务器
    -A 添加虚拟服务器
    -E 修改虚拟服务器
    -D 删除虚拟服务器
    -C, --clear:清除所有虚拟服务。
    -R, --restore:从标准输入获取ipvsadm命令。一般结合下边的-S使用。
    -S, --save:从标准输出输出虚拟服务器的规则。可以将虚拟服务器的规则保存,在以后通过-R直接读入,以实现自动化配置。
    -L, -l, --list:列出虚拟服务表中的所有虚拟服务。可以指定地址。添加-c显示连接表。
    -Z, --zero:将所有数据相关的记录清零。这些记录一般用于调度策略。
    --set tcp tcpfin udp:修改协议的超时时间。
    --start-daemon state:设置虚拟服务器的备服务器,用来实现主备服务器冗余。(注:该功能只支持ipv4)
    --stop-daemon:停止备服务器。
    -h, --help:帮助。
    -t 设置集群地址(VIP,Virtual IP)
    -s 指定负载调度算法
  添加,删除服务器节点
    -a 添加真实服务器
    -e 修改真实服务器
    -d 删除真实服务器
    -r 指定真实服务器(Real Server)的地址
    -m 使用NAT模式
    -g 使用DR模式
    -i 使用TUN模式
    -u, --udp-service service-address:使用udp服务,其他同上。
    -w 为节点服务器设置权重,默认为1,权重是0~65535的整数。如果将某个真实服务器的权重设置为0,那么它不会收到新的连接,但是已有连接还会继续维持(这点和直接把某个真实服务器删除时不同的)
    -f, --fwmark-service integer:用firewall mark取代虚拟地址来指定要被负载均衡的数据包,可以通过这个命令实现把不同地址、端口的虚拟地址整合成一个虚拟服务,可以让虚拟服务器同时截获处理去往多个不同地址的数据包。fwmark可以通过iptables命令指定。如果用在ipv6需要加上-6。
    -p, --persistent [timeout]:设置持久连接,这个模式可以使来自客户的多个请求被送到同一个真实服务器,通常用于ftp或者ssl中。
    -M, --netmask netmask:指定客户地址的子网掩码。用于将同属一个子网的客户的请求转发到相同服务器。
    -x, --u-threshold uthreshold:设置一个服务器可以维持的连接上限。0~65535。设置为0表示没有上限。
    -y, --l-threshold lthreshold:设置一个服务器的连接下限。当服务器的连接数低于此值的时候服务器才可以重新接收连接。如果此值未设置,则当服务器的连接数连续三次低于uthreshold时服务器才可以接收到新的连接。(PS:笔者以为此设定可能是为了防止服务器在能否接收连接这两个状态上频繁变换)
    --mcast-interface interface:指定使用备服务器时候的广播接口。
    --syncid syncid:指定syncid,同样用于主备服务器的同步。
  查看IPVS
    -Ln 查看已经设置了的服务器节点情况

以下选项用于list命令:

  -c, --connection:列出当前的IPVS连接。
  --timeout:列出超时
  --daemon:
  --stats:状态信息
  --rate:传输速率
  --thresholds:列出阈值
  --persistent-conn:坚持连接
  --sor:把列表排序。
  --nosort:不排序
  -n, --numeric:不对ip地址进行dns查询
  --exact:单位

1 ipvsadm命令用法

1.1 问题

准备一台Linux服务器,安装ipvsadm软件包,练习使用ipvsadm命令,实现如下功能:

  • 使用命令添加基于TCP一些的集群服务
  • 在集群中添加若干台后端真实服务器
  • 实现同一客户端访问,调度器分配固定服务器
  • 会使用ipvsadm实现规则的增、删、改
  • 保存ipvsadm规则

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用命令增、删、改LVS集群规则

1)创建LVS虚拟集群服务器

[root@svr5 ~]# ipvsadm -A -t 192.168.0.254 -s wrr -p 

2)为集群添加若干real server

[root@svr5 ~]# ipvsadm –a -t 192.168.0.254 -r 192.168.0.1 -m -w
[root@svr5 ~]# ipvsadm –a -t 192.168.0.254 -r 192.168.0.2 -m -w
[root@svr5 ~]# ipvsadm –a -t 192.168.0.254 -r 192.168.0.3 -m -w
[root@svr5 ~]# ipvsadm –a -t 192.168.0.254 -r 192.168.0.4 -m -w

3)修改集群服务器设置

[root@svr5 ~]# ipvsadm -E -t 192.168.0.254 -s sh -p 

4)修改read server

[root@svr5 ~]# ipvsadm –a -t 192.168.0.254 -r 192.168.0.1 -m

5)查看LVS状态

[root@svr5 ~]# ipvsadm –Ln

6)保存所有规则

[root@svr5 ~]# service ipvsadm save

7)清空所有规则

[root@svr5 ~]# ipvsadm –C

2 部署LVS-NAT集群

2.1 问题

使用LVS实现NAT模式的集群调度服务器,为用户提供Web服务:

  • 集群对外公网IP地址为202.114.106.20
  • 调度器内网IP地址为192.168.0.254
  • 真实Web服务器地址分别为192.168.0.1、192.168.0.2、192.168.0.3
  • 使用加权轮询调度算法,真实服务器权重与其IP地址末尾数一致

2.2 方案

使用4台虚拟机,1台作为Director调度器、3台作为Real Server、物理机作为客户端

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:配置网络环境

1)设置Web服务器网络参数

[root@web1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@web1 ~]# service NetworkManager stop
[root@web1 ~]# chkconfig NetworkManager off
[root@web1 ~]# service network restart
[root@web1 ~]# iptables –F;service iptables save
[root@web2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.2
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@web2 ~]# service NetworkManager stop
[root@web2 ~]# chkconfig NetworkManager off
[root@web2 ~]# service network restart
[root@web2 ~]# iptables –F;service iptables save
[root@web3 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.3
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@web3 ~]# service NetworkManager stop
[root@web3 ~]# chkconfig NetworkManager off
[root@web3 ~]# service network restart
[root@web3 ~]# iptables –F;service iptables save

2)自定义Web页面

[root@web1 ~]# echo “192.168.0.1” > /var/www/html/index.html
[root@web2 ~]# echo “192.168.0.2” > /var/www/html/index.html
[root@web3 ~]# echo “192.168.0.3” > /var/www/html/index.html

3)启动Web服务器软件

[root@web1 ~]# service httpd start
[root@web2 ~]# service httpd start
[root@web3 ~]# service httpd start

4)设置LVS调度器网络参数

[root@lvs ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=202.114.106.20
DNS1=202.106.0.20
[root@lvs ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.254
NETMASK=255.255.255.0
DNS1=202.106.0.20
[root@lvs ~]# service NetworkManager stop
[root@lvs ~]# chkconfig NetworkManager off
[root@lvs ~]# service network restart
[root@lvs ~]# iptables –F;service iptables save
[root@lvs ~]# sed -i '/ip_forward/s/0/1/' /etc/sysctl.conf //开启路由转发
[root@lvs ~]# sysctl -p

步骤二:调度器安装软件并启动服务

1)安装软件

[root@lvs Packages]# rpm –ihv ipvsadm-1.25-.el6.x86_64.rpm

2)启动服务

[root@lvs Packages]# service ipvsadm start
[root@lvs Packages]# chkconfig ipvsadm on

步骤三:部署LVS-NAT模式调度器

1)创建集群服务器

[root@lvs ~]# ipvsadm -A -t 202.114.106.20: -s wrr

2)添加真实服务器

[root@lvs ~]# ipvsadm -a -t 202.114.106.20: -r 192.168.0.1 -m -w
[root@lvs ~]# ipvsadm -a -t 202.114.106.20: -r 192.168.0.2 -m -w
[root@lvs ~]# ipvsadm -a -t 202.114.106.20: -r 192.168.0.3 -m -w

3)查看规则列表,并保存规则

[root@lvs ~]# ipvsadm –Ln
[root@lvs ~]# service ipvsadm save

步骤四:客户端测试

客户端使用curl命令反复连接http://202.114.106.20,查看访问的页面是否会轮询到不同的后端真实服务器。

3 部署LVS-DR集群

3.1 问题

使用LVS实现DR模式的集群调度服务器,为用户提供Web服务:

  • 路由器对外公网IP地址为202.114.106.20
  • 路由器内网IP地址为192.168.0.254
  • 路由是需要设置SNAT及DNAT功能
  • LVS调度器真实IP地址为192.168.0.10
  • LVS调度器VIP地址设置为192.168.0.253
  • 真实Web服务器地址分别为192.168.0.1、192.168.0.2
  • 使用加权轮询调度算法,真实服务器权重与其IP地址末尾数一致

3.2 方案

使用4台虚拟机,1台作为Linux路由器、1台作为Director调度器、2台作为Real Server、物理机作为客户端,拓扑结构如图-2所示。

ARP广播的问题
  当客户端发起访问VIP对应的域名请求时,根据网络通信原理会产生ARP广播
  因为负载均衡器和真实的服务器在同一网络并且VIP设置在集群中的每个节点上
  此时集群内的真实服务器会尝试回答来自客户端的APR广播,这就会产生问题,大家都说自己是"VIP"
  因此真实的主机需要修改arp内核参数
内核参数说明
  arp_ignore(定义回复ARP广播的方式)
    0(默认值)回应所有本地地址ARP广播,本地地址可以配置在任意网络接口
    1只回应配置在入站网卡接口上的任意IP地址的ARP广播
  arp_announce
    0(默认值)使用配置在任意网卡接口上的本地IP地址
    2对查询目标使用最适当的本地地址。在此模式下将忽略这个IP数据包的原地址并尝试选择与能与该地址通信的本地地址。首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址。如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:配置网络环境

1)设置Web服务器网络参数[Linux-eth0 eth0:1 ifcfg-lo ifcfg-lo:0 和eth0.1关系]

[root@web1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
#既然要让RS能够处理目标地址为vip的IP包,首先必须要让RS能接收到这个包。在lo上配置vip能够完成接收包并将结果返回client。
#不可以将VIP设置在出口网卡(eth0)上,否则会响应客户端的arp request,造成client/gateway arp table紊乱,以至于整个loadbalance都不能正常工作。
[root@web1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo:  #本地回环
DEVICE=lo:
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.253
NETMASK=255.255.255.255
[root@web1 ~]# vim /etc/sysctl.conf
.. ..
net.ipv4.conf.all.arp_ignore =
net.ipv4.conf.lo.arp_ignore =
net.ipv4.conf.lo.arp_announce =
net.ipv4.conf.all.arp_announce =
[root@web1 ~]# sysctl -p
[root@web1 ~]# service NetworkManager stop
[root@web1 ~]# chkconfig NetworkManager off
[root@web1 ~]# service network restart
[root@web1 ~]# iptables -F;service iptables save
[root@web2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.2
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@web2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo:
DEVICE=lo:
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.253
NETMASK=255.255.255.255
[root@web2 ~]# vim /etc/sysctl.conf
.. ..
net.ipv4.conf.all.arp_ignore =
net.ipv4.conf.lo.arp_ignore =
net.ipv4.conf.lo.arp_announce =
net.ipv4.conf.all.arp_announce =
[root@web2 ~]# sysctl -p
[root@web2 ~]# service NetworkManager stop
[root@web2 ~]# chkconfig NetworkManager off
[root@web2 ~]# service network restart
[root@web2 ~]# iptables -F;service iptables save

2)自定义Web页面

[root@web1 ~]# echo “192.168.0.1” > /var/www/html/index.html
[root@web2 ~]# echo “192.168.0.2” > /var/www/html/index.html

3)启动Web服务器软件

[root@web1 ~]# service httpd start;chkconfig httpd on
[root@web2 ~]# service httpd start;chkconfig httpd on

4)设置LVS调度器网络参数

[root@lvs ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.10
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@lvs ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0:
DEVICE=eth0:
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.253
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
DNS1=202.106.0.20
[root@lvs ~]# service NetworkManager stop
[root@lvs ~]# chkconfig NetworkManager off
[root@lvs ~]# service network restart
[root@lvs ~]# iptables -F;service iptables save

5)设置Linux路由器网络参数

[root@router ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=202.114.106.20
DNS1=202.106.0.20
[root@router ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.254
NETMASK=255.255.255.0
DNS1=202.106.0.20
[root@router ~]# service NetworkManager stop
[root@router ~]# chkconfig NetworkManager off
[root@router ~]# service network restart
[root@router ~]# iptables -F;service iptables save

6)设置Linux路由器的SNAT、DNAT功能

[root@router ~]# sed -i '/ip_forward/s/0/1/'  sysctl.conf  //开启路由转发
[root@router ~]# sysctl -p
[root@router ~]# iptables -t nat -A POSTROUTING -s 192.168.0.0/ -p tcp –j SNAT --to-source 202.114.106.20
[root@router ~]# iptables -t nat -A PREROUTING -d 202.114.106.20 -p tcp --dport –j DNAT --to-destination 192.168.0.253:
[root@router ~]# service iptables save

步骤二:调度器安装软件并启动服务

1)安装软件

[root@lvs Packages]# rpm –ihv ipvsadm-1.25-.el6.x86_64.rpm

2)启动服务

[root@lvs Packages]# service ipvsadm start
[root@lvs Packages]# chkconfig ipvsadm on

步骤三:部署LVS-DR模式调度器

1)创建集群服务器

[root@lvs ~]# ipvsadm -A -t 192.168.0.253: -s wrr

2)添加真实服务器

[root@lvs ~]# ipvsadm -a -t 192.168.0.253: -r 192.168.0.1 -g -w
[root@lvs ~]# ipvsadm -a -t 192.168.0.253: -r 192.168.0.2 -g -w

3)查看规则列表,并保存规则

[root@lvs ~]# ipvsadm –Ln
[root@lvs ~]# service ipvsadm save

步骤四:客户端测试

客户端使用curl命令反复连接http://202.114.106.20,查看访问的页面是否会轮询到不同的后端真实服务器。

LVS集群简介及使用的更多相关文章

  1. LVS 集群与存储《路由转发》

                                                             LVS 集群与存储<路由转发> 集群简介 u 什么是集群 •  一组通过高 ...

  2. LVS集群和Keepalived高可用实战

    第四十章LVS集群和Keepalived高可用实战 一.ARP协议 1.概念 地址解析协议,即ARP(AddressResolutionProtocol),是根据IP地址获取物理MAC地址的一个TCP ...

  3. 负载均衡之LVS集群

    h3 { color: rgb(255, 255, 255); background-color: rgb(30,144,255); padding: 3px; margin: 10px 0px } ...

  4. LVS集群之NAT模式实现

    LVS集群之NAT模式实现 一.集群的种类 集群系统主要分为 1.HA:高可用集群,又叫双机热备.   (a)原理      2台机器A,B,正常是A提供服务,B待命闲置,当A宕机或服务宕掉,会切换至 ...

  5. LVS集群的体系结构

    2.LVS主要组成部分为: 负载调度器(load balancer/ Director),它是整个集群对外面的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务是来自一个IP地址(我们可称 ...

  6. Linux系统(四)负载均衡LVS集群之NAT模式

    序言 提到LVS,就从章文嵩博士开始吧,反正也不知道如何下笔来写这一篇.章大博士,读博时候创建这个lvs软件项目,但是他提倡开源精神,在用户的建议和反馈中,这个花了他两周时间开发的开源软件不断得到改建 ...

  7. Linux系统(五)负载均衡LVS集群之DR模式

    序言 DR模式是lvs集群中三种负载均衡模式的其中一种,那么上一篇中我写啦关于NAT模式的搭建与原理,为什么还要有DR模式与IP隧道模式呢? 首先我们来看3张图.LVS/NAT模式如下图: LVS/I ...

  8. LVS集群之工作原理和调度算法(2)

      LVS的工作机制 LVS里Director本身不响应请求,只是接受转发请求到后方,Realservers才是后台真正响应请求. LVS 工作原理基本类似DNAT,又不完全相像,它是一种四层交换,默 ...

  9. LVS集群之NAT模式实例(3)

    LVS集群NAT模式实例 1. 实验拓扑图 DS 必须有两块网卡,需要在上面做NAT. 2. 实验环境 3台CentOS6.4 64bit的服务器. 类型 IP DR eth0:10.20.73.20 ...

随机推荐

  1. [OpenCV] Samples 16: Decompose and Analyse RGB channels

    物体的颜色特征决定了灰度处理不是万能,对RGB分别处理具有相当的意义. #include <iostream> #include <stdio.h> #include &quo ...

  2. [Linux] 设置系统时区

    1. 检查当前时区 以 root 身份登录. # date Fri Sep :: UTC 其中 UTC 是指当前使用的时间系统为世界标准时间,也称世界协调时间.英文名称为 Coordinated Un ...

  3. maven子项目的springboot配置

    正常来说一个maven子项目的parent是父项目,而不是直接继承,这时候就需要改下配置 默认生成的代码入下: <?xml version="1.0" encoding=&q ...

  4. Flask web开发之路九

    flask_scripts介绍 项目结构如下: flask_script_demo.py文件: from flask import Flask app = Flask(__name__) @app.r ...

  5. 标准库 os、sys、logging、configparser、time、requests

    os : 与操作系统交互的模块 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于 ...

  6. 制作tomcat重启.bat文件

    环境是在windows下,linux不知道,没有尝试过,有机会去试试哈哈 首先创建一个restart.bat文件 创建在哪里看你开心咯 然后用记事本打开 输入以下源代码: @echo off cd / ...

  7. ubuntu下能ping通ssh不通的解决思路

    1.首先看看是否能ping通,如果ping不通可能就要考虑网线.路由等问题了: 2.看防火墙是否关闭,sshd是否开启 3.ssh -v 服务器的ip号,根据提示寻找可能的问题: 我的问题在这一步之后 ...

  8. tensorflow scope的作用

    我们在使用tensorflow的时候,当你想复用一个函数的模块,调试时候回提示你变量已经出现,提示你是否重用.那我们当然是不重用的,因为每一个变量都是我们需要的. 要体现不同,就在不同的变量中使用na ...

  9. Java进阶面试题大集合-offer不再是问题

    Java基础 1.List 和 Set 的区别 2.HashSet 是如何保证不重复的 3.HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)? 4.HashMap ...

  10. Exception 03 : org.hibernate.MappingException: Unknown entity: org.hibernate.cfg.Configuration

    异常名称 org.hibernate.MappingException: Unknown entity: org.hibernate.cfg.Configuration 异常详细信息 org.hibe ...