VIP 原理和特点

本文介绍了Oracle RAC中的VIP技术原理及其特点。VIP技术确保了在节点出现故障时,其VIP能自动转移到其他节点,从而实现无缝切换。文章详细解释了故障转移过程中的关键步骤。
VIP 原理和特点
Oracle 的TAF 就是建立在VIP 技术之上的。 IP 和VIP 区别在与: IP 是利用TCP层超时, VIP 利用的是应用层的立即响应。VIP 它是浮动的IP. 当一个节点出现问题时会自动的转到另一个节点上。
<wbr><br> ☆☆★(81589007) 9:20:25<br> 假设有一个2个节点的RAC,正常运行时每个节点上都有一个VIP。 VIP1 和VIP2. 当节点2发生故障,比如异常关系。 RAC 会做如下操作:<br> 1). CRS 在检测到rac2节点异常后,会触发Clusterware 重构,最后把rac2节点剔除集群,由节点1组成新的集群。<br> 2). RAC的Failover 机制会把节点2的VIP转移到节点1上,这时节点1的PUBLIC 网卡上就有3个IP 地址: VIP1,VIP2, PUBLIC IP1.<br> 3). 用户对VIP2的连接请求会被IP层路由转到节点1<br> 4). 因为在节点1上有VIP2的地址,所有数据包会顺利通过路由层,网络层,传输层。<br> 5). 但是,节点1上只监听VIP1和public IP1的两个IP地址。并没有监听VIP2,故应用层没有对应的程序接收这个数据包,这个错误立即被捕获。<br> 6). 客户段能够立即接收到这个错误,然后客户段会重新发起向VIP1的连接请求。<br><wbr><wbr> VIP 特点:<br><wbr><wbr><wbr><wbr> 1). VIP 是通过VIPCA脚本创建的<br><wbr><wbr><wbr><wbr> 2). VIP 作为Nodeapps类型的CRS Resource 注册到OCR中,并由CRS 维护状态。<br><wbr><wbr><wbr><wbr> 3). VIP 会绑定到节点的public 网卡上,故public 网卡有2个地址。<br><wbr><wbr><wbr><wbr> 4). 当某个节点发生故障时,CRS 会把故障节点的VIP 转移到其他节点上。<br> 5). 每个节点的Listener 会同时监听public 网卡上的 public ip 和VIP<br> 6). 客户端的tnsnames.Ora 一般会配置指向节点的VIP.<br></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
//1.mesh构建 using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider))] public class Potteryprototype : MonoBehaviour {     MeshFilter meshFilter;     MeshRenderer meshRenderer;     MeshCollider meshCollider;     Mesh mesh;       public int details = 40;     public int layer = 20;     public float Height = 0.1f;       public float OuterRadius = 1.0f;     public float InnerRadius = 0.9f;       List<Vector3> vertices;     List<Vector2> UV;     List<int> triangles;       float EachAngle ;     int SideCount;       public MouseControl mouse;       void Start()     {         meshFilter = GetComponent<MeshFilter>();         meshCollider = GetComponent<MeshCollider>();         meshRenderer = GetComponent<MeshRenderer>();     }       [ContextMenu("GeneratePottery")]     void GeneratePrototype()     {         vertices = new List<Vector3>();         triangles = new List<int>();         UV = new List<Vector2>();           EachAngle = Mathf.PI * 2 / details;         for (int i = 0; i < layer; i++)         {             GenerateCircle(i);         }         Capping();                 mesh = new Mesh();         mesh.vertices = vertices.ToArray();         mesh.triangles = triangles.ToArray();         mesh.uv = UV.ToArray();           mesh.RecalculateBounds();         mesh.RecalculateTangents();           meshFilter.mesh = mesh;         mesh.RecalculateNormals();         meshCollider.sharedMesh = mesh;     }       void GenerateCircle(int _layer)     {         //外顶点与内顶点分开存储,方便变化操作时的计算         List<Vector3> vertices_outside = new List<Vector3>();         List<Vector3> vertices_inside = new List<Vector3>();                  List<Vector2> UV_outside = new List<Vector2>();         List<Vector2> UV_inside = new List<Vector2>();             //外侧内侧顶点计算         //注意这里让每一圈的首尾重合了,也就是开始结尾的顶点坐标一致         //目的是计算UV坐标时不会出现空缺         for (float i = 0; i <= Mathf.PI * 2+EachAngle; i += EachAngle)         {             Vector3 v1 = new Vector3(OuterRadius * Mathf.Sin(i),  _layer * Height, OuterRadius * Mathf.Cos(i));             Vector3 v2 = new Vector3(OuterRadius * Mathf.Sin(i),  (_layer +1)* Height, OuterRadius * Mathf.Cos(i));             Vector3 v3 = new Vector3(InnerRadius * Mathf.Sin(i),  _layer * Height, InnerRadius * Mathf.Cos(i));             Vector3 v4 = new Vector3(InnerRadius * Mathf.Sin(i),  (_layer+1) * Height, InnerRadius * Mathf.Cos(i));             vertices_outside.Add(v1); vertices_outside.Add(v2);             vertices_inside.Add(v3); vertices_inside.Add(v4);               Vector2 uv1 = new Vector2(i / Mathf.PI*2, _layer*1.0f / layer * 1.0f);             Vector2 uv2 = new Vector2(i / Mathf.PI*2, (_layer + 1)*1.0f / layer * 1.0f);             Vector2 uv3 = new Vector2(i / Mathf.PI*2, _layer*1.0f / layer * 1.0f);             Vector2 uv4 = new Vector2(i / Mathf.PI*2, (_layer + 1) *1.0f/ layer * 1.0f);             UV_outside.Add(uv1); UV_outside.Add(uv2);             UV_inside.Add(uv3); UV_inside.Add(uv4);         }         vertices.AddRange(vertices_outside);         vertices.AddRange(vertices_inside);           UV.AddRange(UV_outside);         UV.AddRange(UV_inside);           SideCount = vertices_outside.Count;         int j = vertices_outside.Count * _layer * 2;         int n = vertices_outside.Count;         for (int i = j; i < j + vertices_outside.Count - 2; i += 2)         {               triangles.Add(i); triangles.Add(i + 2); triangles.Add(i + 1);             triangles.Add(i + 2); triangles.Add(i + 3); triangles.Add(i + 1);               triangles.Add(i + n); triangles.Add(i + n + 1); triangles.Add(i + n + 2);             triangles.Add(i + n + 2); triangles.Add(i + n + 1); triangles.Add(i + n + 3);         }          }     //封顶,底面由于看不见就不用管了     void Capping()     {                 for (float i = 0; i <= Mathf.PI * 2+EachAngle; i += EachAngle)         {             Vector3 outer = new Vector3(OuterRadius * Mathf.Sin(i),layer * Height, OuterRadius * Mathf.Cos(i));             Vector3 inner= new Vector3(InnerRadius * Mathf.Sin(i), layer * Height, InnerRadius * Mathf.Cos(i));               vertices.Add(outer);vertices.Add(inner);               Vector2 uv1 = new Vector2(i / Mathf.PI * 2,0); Vector2 uv2 = new Vector2(i / Mathf.PI * 2, 1);                         UV.Add(uv1); UV.Add(uv2);         }         int j = SideCount * layer * 2;         for (int i=j;i<vertices.Count-2;i+=2)         {             triangles.Add(i);triangles.Add(i + 3);triangles.Add(i + 1);             triangles.Add(i);triangles.Add(i + 2);triangles.Add(i + 3);         }         triangles.Add(vertices.Count - 2);triangles.Add(j + 1);triangles.Add(vertices.Count - 1);         triangles.Add(vertices.Count - 2);triangles.Add(j);triangles.Add(j + 1);             } }   //2.动态改变形状 //这个函数放在Update()里调用     void GetMouseControlTransform()     {         //从屏幕鼠标位置发射一条射线到模型上,获取这个坐标         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);         RaycastHit info;           if (Physics.Raycast(ray.origin, ray.direction, out info))         {               //在Unity中无法直接修改MeshFilter中Mesh的信息,需要新建一个Mesh修改其引用关系             Mesh mesh = meshFilter.mesh;             Vector3[] _vertices = mesh.vertices;               for (int i = 0; i < _vertices.Length; i++)             {                   //x,z平面变换                 //顶点移动与Y值的关系限制在5倍单层高度                 //这里可以自行修改,限制高度越大,曲线越平滑                 if (Mathf.Abs(info.point.y - transform.TransformPoint(_vertices[i]).y) < (5 * Height))                 {                     //计算顶点移动方向的向量                     Vector3 v_xz = (transform.TransformPoint(_vertices[i]) - new Vector3(transform.position.x, transform.TransformPoint(_vertices[i]).y, transform.position.z));                       //外顶点与内顶点移动时相对距离应该保持不变                     //因为我们知道顶点数组内的顺序关系,所以可以通过计算总顶点数除以每层单侧顶点数的商的奇偶关系来判断是外顶点还是内顶点                     int n = i / SideCount;                     bool side = n % 2 == 0;                     //判断顶面顶点内外关系                     bool caps = (i - (SideCount * layer * 2)) % 2 == 0;                       //限制每个顶点最大最小的移动距离                     float max;                     float min;                     if (i < SideCount * layer * 2)                     {                         max = side ? 2f * OuterRadius : 2f * OuterRadius - (OuterRadius - InnerRadius);                           min = side ? 0.5f * OuterRadius : 0.5f * OuterRadius - (OuterRadius - InnerRadius);                     }                     else                     {                         max = caps ? 2f * OuterRadius : 2f * OuterRadius - (OuterRadius - InnerRadius); ;                         min = caps ? 0.5f * OuterRadius : 0.5f * OuterRadius - (OuterRadius - InnerRadius);                     }                     //计算当前顶点到鼠标Y值之间的距离,再用余弦函数算出实际位移距离                     float dif = Mathf.Abs(info.point.y - transform.TransformPoint(_vertices[i]).y);                     if (Input.GetKey(KeyCode.RightArrow))                     {                         float outer = max - v_xz.magnitude;                         _vertices[i] += v_xz.normalized * Mathf.Min(0.01f * Mathf.Cos(((dif / 5 * Height) * Mathf.PI) / 2), outer);                     }                     else if (Input.GetKey(KeyCode.LeftArrow))                     {                         float inner = v_xz.magnitude - min;                         _vertices[i] -= v_xz.normalized * Mathf.Min(0.01f * Mathf.Cos(((dif / 5 * Height) * Mathf.PI) / 2), inner);                     }                       //Y轴变换                     float scale_y = transform.localScale.y;                     if (Input.GetKey(KeyCode.UpArrow))                     {                         scale_y = Mathf.Min(transform.localScale.y + 0.000001f, 2.0f);                     }                     else if (Input.GetKey(KeyCode.DownArrow))                     {                           scale_y = Mathf.Max(transform.localScale.y - 0.000001f, 0.3f);                     }                     transform.localScale = new Vector3(transform.localScale.x, scale_y, transform.localScale.z);                   }                   mesh.vertices = _vertices;                 mesh.RecalculateBounds();                 mesh.RecalculateNormals();                 meshFilter.mesh = mesh;                 meshCollider.sharedMesh = mesh;             }         }     } }   //计算时就把顶点坐标系转换为自身坐标系,求得向量后再转换为世界坐标系     Vector3 v_xz = transform.TransformDirection(transform.InverseTransformPoint(_vertices[i]) - transform.InverseTransformPoint(new Vector3(0, _vertices[i].y, 0)));   //3.法线平均化 IEnumerator Print_Normals()     {              for (int i = 0; i < meshFilter.mesh.vertices.Length; i++)         {                if (i % 2 == 0)             {                 Debug.DrawRay(transform.TransformPoint(meshFilter.mesh.vertices[i]), transform.TransformDirection(meshFilter.mesh.normals[i] * 0.3f), Color.green, 1000f);             }             else             {                 Debug.DrawRay(transform.TransformPoint(meshFilter.mesh.vertices[i]), transform.TransformDirection(meshFilter.mesh.normals[i] * 0.3f), Color.blue, 1000f);             }               yield return new WaitForSeconds(Time.deltaTime);           }     }   //回到项目上来。这段法线计算的代码就不放上来了,大致就是根据顶点在数组中的下标去判断位置是否相同,然后把该顶点的法线相加即可。大家自己构建Mesh时的顶点顺序可能会不太一样。 以上代码是否有问题,请帮我完善
最新发布
08-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值