应用迁移与适配技术

目录

一、介绍

二、为什么要软件迁移

三、怎么迁移

(一)、C/C++编译型语言迁移

​编辑

(二)、Java解释型语言移植

总结

应用迁移技术

应用适配技术


一、介绍

(一)、应用迁移

       应用迁移是指将软件应用从一个计算环境迁移到另一个环境的过程。例如,可以将应用从一个数据中心迁移到另一个数据中心,从本地服务器迁移到云提供商环境,或从公有云迁移到私有云环境。由于应用通常设计为在特定网络架构中的特定操作系统上运行,或者是针对单一云平台开发的,因此将应用迁移到新环境可能会带来一系列挑战。

在迁移过程中,需要考虑以下几个方面:

  1. 硬件评估:评估目标环境的硬件设备是否满足应用运行的要求,包括CPU、内存、存储等。
  2. 软件评估:评估目标环境的操作系统、数据库、中间件等软件环境是否与应用兼容。
  3. 迁移策略:选择适合应用的迁移策略,如在线迁移、离线迁移等。
  4. 迁移测试:在迁移完成后,对应用进行测试以确保其在新环境中能够正常运行。

(二)、应用适配

       应用适配是指将软件或系统适应不同的使用环境、使用条件或用户需求的一种技术手段。在不同的应用场景下,可能需要调整软件的功能、界面、交互方式等方面,以最大程度地满足用户的需求。

        应用适配主要包括硬件适配和软件适配两种方式:

  1. 硬件适配:将软件与硬件设备相结合,针对不同的硬件设备进行适配。例如,对于不同的操作系统、不同的硬件设备,可能需要调整软件的安装、配置和运行方式。
  2. 软件适配:根据不同的应用场景,对软件进行相应的调整,以更好地适应不同的用户需求。例如,可以通过调整软件的界面、交互方式、功能设置等来满足不同用户的需求。

在实现应用适配时,可以采用一些技术手段来确保应用在不同环境下的兼容性,如使用响应式布局、百分比布局、资源限定符等。此外,还可以使用一些工具来辅助实现应用适配,如CSS媒体查询、Android平台的资源限定符机制等。

二、为什么要软件迁移

     x86 和鲲鹏 ARM 架构之间最大的区别源自于指令集的不同。以下图的 C/C++程序代码中的“c=a+b”语句为例,我们可以看到其通过编译器编译汇编指令后.

应用需要迁移的原因:

1.汇编代码角度

同样的C语言代码,在编译成不同架构下的程序后,得到的汇编代码是不同的,这些不同点主要体现在以下3个方面:

1.1 处理器指令 

以简单的给变量赋值操作为例:

(1)鲲鹏架构。 

首先使用mov指令把操作数传送给寄存器,然后使用ldr指令把寄存器的值传送到内存。 

(2)x86架构。 

直接使用movl指令把操作数传送到内存。 

鲲鹏架构和x86架构在具体的处理器指令设计上,是有重大区别的,同样的功能,两个架构的处理器指令实现的方式可能不一样。 

1.2 寄存器 

这一点也比较明显,两个架构下的寄存器不管是数量还是功能都有所不同。

(1)鲲鹏架构。

ARM 64有34个寄存器,其中编号x0~x29是通用寄存器,x30为程序链接寄存器,x31比较特殊,它有时候用作xzr零寄存器,有时候是栈指针寄存器sp,两者不能在一条指令里共存,另外两个寄存器是程序计数器PC、状态寄存器CPSR。

ARM 64寄存器x0~x30及xzr零寄存器都是64位的,它们的低32位构成了32位寄存器,分别用w0~w30表示,用wzr表示32位下的零寄存器。

除此之外,ARM 64还有浮点寄存器和向量寄存器。

(2)x86-64架构。

x86-64架构下有16个64位的通用寄存器,这些寄存器支持访问低位,例如访问低8位、低16位、低32位。

1.3 指令长度 

x86下指令的长度是不一样的,短的只有1字节,而长的却有15字节,给寻址带来了一定的不便。

鲲鹏架构指令长度为固定的32位(ARM工作状态),寻址方便,效率较高。

三、怎么迁移

(一)、C/C++编译型语言迁移

       C/C++作为典型的编译型语言,由于架构、指令集、向量寄存器的差异,程序在从 x86→鲲鹏处理器时,必须经过重新编译才能运行。
       从代码工程的角度来看,C/C++的文件分为两类,一是编译构建的脚本,二是源码。其中:

1、编译构建脚本类文件在迁移过程中一般会涉及编译选项的移植,包括指定数据类型、生成代码特性、目标执行器架构、处理器硬件加速功能等。
2、源码文件的迁移,一般会涉及到编译宏的移植、编译器自带 builtin 函数移植、内联汇编移植、SSE intrinsic 函数移植等。

       下图展示了 C/C++代码完整的编译构建过程。首先通过 GitHub 和第三方开源社区获取相应的源码。其次安装 gcc 版本,准备编译环境。之后使用源码中的 CMakeLists.txt 或 configure 脚本生成 makefile。随后执行 makefile 编译可执行程序,并替换依赖库。最后,将可执行程序安装部署到生产或测试系统。

在Arm架构(鲲鹏920)的麒麟操作系统V10

步骤1 编写C语言Hello World

#vim hello.c

#include <stdio.h>
int main()
{
  printf("hello world");
  return 0;
}

步骤2 GCC编译

#gcc hello.c -E -o hello.i 

可以通过cat 查看hello.i 会发现加入很多额外的代码。

1、gcc hello.c -S -c -o hello.s 包含预处理,将 C 程序转换成汇编程序

-S 编译到汇编语言,不进行汇编和链接

-c  编译、汇编到目标代码,不进行链接

#gcc hello.c -S -c -o hello.s

2、gcc hello.c -c -o hello.o 汇编:包含预处理和编译,将汇编程序转换成可链接的二进制程序。

#gcc hello.c -c -o hello.o

因为.o文件是二进制文件,所以直接用cat查看,看到的是乱码。

3、gcc hello.c -o hello 链接:包含以上所有操作,将可链接的二进制程序和其它别的库链接在一起,形成可执行的程序文件。

#gcc hello.c -o hello

我们可以通过objdump来查看

 #objdump -d hello.o

以上图中,分成三部分:

第一部分为地址;

第二部分为十六进制,表示真正装入机器中的代码数据;

第三部分是对应的汇编代码;

这是 x86_64 体系的代码,由此可以看出 x86 CPU 是变长指令集

小结:

对于C/C++为代表的编译型语言来说,移植方法一般包括两种,也就是源代码修改和编译选项修改,有时候使用其中一种方式,有时候两种方式需要同时使用。

(二)、Java解释型语言移植

查询本地的java环境

分别在X86架构的麒麟操作系统V10,Arm架构(鲲鹏920)的麒麟操作系统V10环境下执行以下命令

步骤1 查看本机已经安装的java版本。

#yum search java

麒麟默认提供了java1.8,java-11两套java开发环境。可以依据实际情况自行确定。

我们这里选用java1.8作为开发环境

步骤2 安装java的相关开发环境

yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel java-1.8.0-openjdk-headless -y
本地安装java1.8的环境

yum remove java-11-openjdk-devel java-11-openjdk java-11-openjdk-headless -y
删除java-11

步骤3 验证java,javac的版本

[root@jd4 tmp]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment Bisheng (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM Bisheng (build 25.292-b10, mixed mode)
[root@jd4 tmp]# javac -version
javac 1.8.0_292

在两台主机上均完成以上操作,则可以进入下一步骤。

纯java代码迁移

x86架构下完成以下操作,配套代码可以在java_demo目录中查找

步骤1 编写java测试代码

mkdir -pv /usr/local/src/code/java_demo
cd /usr/local/src/code/java_demo
vim Demo.java

import java.util.Scanner;

public class Demo{
    public static void main(String[] args){
      Scanner sc = new Scanner(System.in);
      String input = sc.nextLine();
      System.out.println(input);
      sc.close();
    }
}

步骤2 编译并执行

[root@node1 java_demo]#javac Demo.java
[root@node1 java_demo]# ls
Demo.class  Demo.java
java Demo

​​​​​​​

你输入什么,就会显示什么,如下图

在x86架构下编译及运行没问题了,把这个编译好的.class文件 复制到鲲鹏架构的服务器上。

步骤3 移植java代码

把x86架构下环境下编写的java代码拷贝到Arm架构环境。在Arm 环境完成以下操作:

先确认环境

[root@jd4 tmp]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment Bisheng (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM Bisheng (build 25.292-b10, mixed mode)
[root@jd4 tmp]# javac -version
javac 1.8.0_292

​​​​​​​​​​​​​​

拷贝java代码

在x86主机执行

[root@node1 java_demo]# scp Demo.class 179.119.224.2:/tmp
The authenticity of host '179.119.224.2 (179.119.224.2)' can't be established.
ECDSA key fingerprint is SHA256:QBfezyONvuiNbSmao2ml3MjaZX/BMllINTtPJ4TetJk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '179.119.224.2' (ECDSA) to the list of known hosts.

Authorized users only. All activities may be monitored and reported.
root@179.119.224.2's password:
Demo.class


这里的ip地址请根据实际情况修改纯文

步骤4 执行java代码,并验证

在arm主机执行

[root@jd4 ~]# cd /tmp/
[root@jd4 tmp]# java Demo
hello java
hello java

Netty是开源的项目,在获得所有的源代码后,可以通过对代码 进行重新编译的方式来执行迁移。因为代码里有Java和C语言,并且 Netty项目是通过Pom进行项目组织管理的,在迁移时不但要安装C的 编译环境,还要安装openjdk和Maven。

步骤1 通过yum 安装依赖环境

#yum install gcc gcc-c++ make cmake3 libtool autoconf automake 
ant wget git openssl openssl-devel apr-devel ninja-build -y

步骤2 安装Maven

下载Maven

#cd /usr/local/src
#wget http://archive.apache.org/dist/maven/maven-3/3.5.4/
binaries/apache-maven-3.5.4-bin.tar.gz

解压缩

#cd /usr/local/src
#tar fvxz apache-maven-3.5.4-bin.tar.gz
#mv apache-maven-3.5.4 /opt/maven

修改环境变量

vim /etc/profile
MAVEN_HOME=/opt/maven
PATH=$MAVEN_HOME/bin:$PATH
export MAVEN_HOME PATH

#执行下面的命令更新环境变量
​​​​​​​​​​​​​​

source /etc/profile

​​​​​​​

查看版本

mvn -version

修改maven的配置文件,更改镜像仓库网址为国内的镜像网址。

 vim /opt/maven/conf/settings.xml
     <mirror>
      <id> huawei </id>
      <name>huawei maven</name>
      <url>https://mirrors.huaweicloud.com/repository/maven/</url>
      <mirrorOf>central</mirrorOf>
    </mirror>

步骤3 修改gcc、g++ 默认编译选项

鲲鹏架构中char类型问题

设置gcc和g++的编译选项来处理,也就是把这两个编译器的编译 加上-fsigned-char的选项。

给gcc加一个壳

[root@jd4 src]# which gcc
/usr/bin/gcc
[root@jd4 src]# mv /usr/bin/gcc /usr/bin/gcc_bak  cp
[root@jd4 src]# vim /usr/bin/gcc
#!/usr/bin/env bash
/usr/bin/gcc_bak -fsigned-char "$@"

[root@jd4 src]# chmod +x /usr/bin/gcc
[root@jd4 src]# gcc --version
gcc_bak (GCC) 7.3.0
Copyright © 2017 Free Software Foundation, Inc.

看到下图,就代表gcc 加壳替换成功了。

小结:

在一个Java程序执行时,首先通过javac把java文件编译为虚拟机可以识别的class文件。 然后由JVM解释器解释class文件中的字节码,通过JVM把解释结果转变为机器码执行。 这是我们通常所说的解释执行。所以,纯Java语言编写的程序不需要重新编译。有依赖的So库需要迁移,可以先安装好编译需要的GCC与Maven,然后在新平台下重新编译So库。

CPU 和内存

CPU 和内存优化的两大方向分别是软加速和硬加速,软加速主要涉及编译优化、NUMA-Aware 亲和性优化。编译器优化主要是针对鲲鹏芯片的微架构,优化了寄存器的分配、指令的部署和流水,提升大部分指令的执行效率。具体来讲,主要分为布局优化、内存布局优化、以及循环优化等;NUMA-Aware 主要是减少内存的跨片和跨 NUMA 访问时产生时延,提高多核架构下面的并行度。此外,硬件加速则是鲲鹏处理器为性能提升提供的一个核武器。

磁盘

因为内存和 CPU 的高速缓存大小都是有限的,我们需要访问的数据大多存在磁盘上或者网络存储上。因此文件系统决定了磁盘加载到内存过程的快慢。华为鲲鹏提供了 EX3、EX14、以及 XFS 等数据访问的管理模式,能够有效提高访问磁盘的性能。

网卡

主要需要根据实际应用场景来调整 frames 和 usecs 两个特性,根据延时和带宽需求来权衡控制两个参数。

应用层

开发者可以提高并发数、优化缓存操作、启用异步读写等,针对鲲鹏平台的系统特性进行整体配置。

在具体的性能调优实践中,第一步就是选择调优方向,包括三大块硬件和应用;第二步是性能采集、分析性能瓶颈、定位热点函数;第三步是针对平台特性充分利用硬件资源;第四步是要在网络端寻求合适的参数平衡点。

  1. 编译型语言

编译型语言的代表是C/C++等语言,使用编译型语言编写的源代码经过一系列的编译过程,最终才能生成可执行程序,因为不同架构下指令集不同,导致依赖于指令集的二进制机器码、汇编语言都不同,所以同一段程序,在不同的架构下,需要最终编译成和架构相适应的二进制机器码。

  1. 解释型语言

解释型语言的代表是Java/Python等语言,Java的源代码会被编译成字节码,字节码运行在Java虚拟机JVM上,JVM具有与平台架构无关的指令集,同一段Java代码在不同的架构下都可以编译成相同的字节码。JVM对字节码进行解释,转换为物理CPU对应的机器码进行实际执行。因为不同的指令集架构可以适配不同的JVM实现,所以Java等解释型语言只需编译一次,就可以到处运行,不同架构下的JVM屏蔽了指令集之间的差异。

如果一个应用是使用纯Java语言编写的,理论上基本可以跨平台运行,但是实际情况比较复杂,有些Java应用会引用so库文件,这些so库文件很有可能是通过编译型语言例如C来编写的,这时候就要考虑so库文件的移植。

总结

应用迁移技术

定义
应用迁移是指将现有的软件应用从一个计算环境(如硬件、操作系统、云平台等)迁移到另一个环境的过程。

主要挑战

  1. 兼容性:确保应用在新环境中与硬件、操作系统、数据库和其他依赖项兼容。
  2. 数据迁移:迁移应用所依赖的数据,并确保数据的完整性和安全性。
  3. 性能优化:优化应用在新环境中的性能,以确保其满足业务需求。
  4. 业务连续性:在迁移过程中确保业务的连续性,尽量减少停机时间。

迁移策略

  1. 离线迁移:在关闭应用后进行迁移,通常适用于对停机时间要求不高的场景。
  2. 在线迁移:在保持应用运行的同时进行迁移,对技术要求较高,但可确保业务的连续性。

实施步骤

  1. 评估:评估现有环境和目标环境,确定迁移的可行性和风险。
  2. 规划:制定详细的迁移计划,包括时间表、资源分配、风险应对措施等。
  3. 测试:在迁移前对应用进行充分的测试,确保其在目标环境中能够正常运行。
  4. 执行:按照计划执行迁移操作。
  5. 验证:在迁移完成后对应用进行验证,确保其在新环境中满足业务需求。

应用适配技术

定义
应用适配是指根据目标环境的特点和用户需求,对软件应用进行调整和优化,以确保其能够在不同环境中正常运行并满足用户需求。

主要挑战

  1. 硬件适配:确保应用能够在不同的硬件设备上正常运行。
  2. 软件适配:确保应用能够与不同的操作系统、数据库、中间件等软件环境兼容。
  3. 用户界面适配:确保应用的用户界面能够在不同的设备(如手机、平板、电脑等)和操作系统上正确显示和操作。

适配策略

  1. 使用标准接口:通过采用标准的硬件和软件接口,减少适配的复杂性。
  2. 多版本支持:为不同的操作系统和硬件平台提供不同的应用版本。
  3. 响应式设计:使用响应式设计技术,使应用的用户界面能够自动适应不同的设备和屏幕尺寸。

实施步骤

  1. 需求分析:了解目标环境的特点和用户需求。
  2. 设计适配方案:根据需求分析结果,设计适配方案,包括硬件适配、软件适配和用户界面适配等。
  3. 开发:按照适配方案进行开发,实现应用的适配功能。
  4. 测试:在目标环境中对应用进行测试,确保其能够适应不同的环境和满足用户需求。
  5. 发布:将适配后的应用发布到目标环境,供用户使用。
  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值