云原生之深入解析K8s中的微服务项目设计与实现

一、微服务项目的设计

① 微服务设计的思想

  • 一个单片应用程序将被构建、测试并顺利地通过这些环境。事实证明,一旦投资于将生产路径自动化,那么部署更多的应用程序似乎就不再那么可怕了。请记住,CD的目标之一就是让部署变得无聊,所以无论是一个应用程序还是三个应用程序,只要它仍然无聊就没关系。
  • 使用基础设施自动化的另一个领域是在生产环境中管理微服务,与我们上面的断言相反,只要部署是无聊的,那么单体服务和微服务之间就没有太大的区别,两者的运营环境可能截然不同。

在这里插入图片描述

  • 微服务把各个功能拆开了,每个模块的功能更加独立,也更加单一,每个模块都独立发展,可以说做到了功能的高内聚,低偶合:

在这里插入图片描述

  • 这样数据库也被彻底拆分开了。一个巨大复制的单体数据库也按照功能拆成了小的独立数据库。微服务就是这么简单吗?当然不是,里面有很多细节需要考虑,纸上得来终觉浅,绝知此事要躬行。

② 实践设计和改进

  • 现在要设计一个最简单的微服务架构,为了更贴近真实的业务,假设这个系统是这样的:

在这里插入图片描述

  • 整个系统的前端是一个有着前后端分离站点,用户访问了 www.demo.com 这个前端站点,通过前端页面发起请求,www.demo.com 服务器将请求发往 a.demo.com,然后 a.demo.com 再请求 b.demo.com,b.demo.com 再请求 c.demo.com,c.demo.com 将结果返回后,不断返回,最终显示在前端站点,完成微服务的全套调用流程。[ 一般业务系统在前端和微服务之间还存在一个网关部分,网关一般用于鉴权,请求分类,监控等功能],最终可以将这套架构将部署在 Kubernetes 上,开始真正的服务用户。

③ 改进项目

  • 从上图中可以看到这是一个非常简单而单薄的架构,存在很多问题,需要不断地解决它们。首先,要解决节点的可靠性,所有的节点都只有一个实例,任何节点的崩溃都将造成项目无法运行,在真正的项目中这是不可接受的,怎么解决呢?当然是多个实例。
  • 加入多实例及注册中心:

在这里插入图片描述

    • 将各个模块的实例数目增加,多个实例才能保证整个系统的可靠性,如果一个实例有问题,还是可以其他相同的实例进行服务。但是多个实例又带来一个问题,各个组件之间如何定位呢?如果有 10 个 b.demo.com 实例,它的上下游又该如何找到它们呢?解决方案之一是注册中心。
    • 注册中心解决的是应用之间的寻址问题。有了它,上下游之间的应用可以相互寻址,并且获知那些实例是可用的,应用挑选可用的实例进行工作。注册中心的方案很多,有 Eureka,ZooKeeper,Consul,Nacos 等。
    • 在 Kubernetes 中部署微服务,对注册中心是没有任何限制的,完全可以做到代码零修改,直接在 Kubernetes 上运行。
  • 监控系统 Metrics:
    • 在完成了注册中心的功能后,虽然整个系统可以运行了,可以发现没有应用监控的情况下,对系统运转状态是完全摸黑的,这样相当于盲人骑马,非常危险。我们需要知道所有微服务运行的状态,必须将各个微服务的状态监控起来,只有这样才能做到 运筹帷幄,决胜千里。

在这里插入图片描述

    • 在这里选择使用 Prometheus 和 Grafana 这套监控组合,Prometheus + Grafana 是一个比较常见的组合,基本是现在容器监控的标准配置。在 Kubernetes 上,我们需要每个微服务的实例里开启监控数据到导出功能。同时利用 Prometheus 的自动发现功能, 这样 Prometheus 可以将数据收集存储起来。这里的数据包括每个应用的各项指标比如内存大小,200 错误数目,500 错误数目,JVM 里线程数量,GC 时间大小。配合 Grafana 的聚合显示能力,我们可以直观地对整个系统有完整把控。在应用开发过程中,我们只需要在代码里加入一个类库就可以实现信息的导出,不需要专门写代码。
  • 日志系统 Logging:
    • 目前已经有了监控,日志还有存在的必要吗?当然,下面这个图就反应监控的 3 个维度:

在这里插入图片描述

    • 这 3 个维度分别是 Mertics,Tracing 和 Logging:
      • Metrics 主要就是指刚才说的监控,它主要反应的就是一个聚合的数据,比如今天 200 错误是多少,QPS 是多少,它指的是一段时间内的数据聚合;
      • Logging 就是现在讨论的日志,它描述一些离散的(不连续的)事件,比如各个系统里的错误、告警,因此需要将日志收集起来;
      • Tracing 则关注单次请求中信息,关注请求的质量和服务可行性,是优化系统,排查问题的工具。
    • 说到了日志,在一个分布式系统,日志是非常重要的一环。因为微服务和容器的缘故,导致日志收集不是这么简单了,因为在 Kubernetes 里容器的销毁和重启都是经常可能出现的,需要第一时间就把日志收集起来。
    • 日志收集的方案有很多,有些方案是在本地启动一个收集进程,将落地的日志转发到 Kakfa 组件再转发日志中心,也有的方案是直接写到 Kafka 组件直接进入日志中心,两者各有优劣。
    • 在这里,方案选择了后者,简单地利用一个组件将日志直接打入 Kafka 组件,这种方案的好处是我们日志不再落地,日志 IO 被消除了,日志的存储也和容器做到了分离,再也不用担心日志 IO 对宿主机造成的系统压力。

在这里插入图片描述

  • 追踪系统 Tracing:
    • 刚才讨论了监控(Metric)和日志(Logging),还有一个维度就是追踪(Tracing),随着微服务的实例越来越多,有一个很现实的问题出现了,当大规模分布式集群出现了,应用构建在不同的容器集群里、有可能布在了几千台容器里,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具,这该怎么解决呢?

在这里插入图片描述

    • Google 的论文描述一种解决办法,我们一般称作 APM(Application Performance Monitor),它把一次调用加入一个独立无二的标记,并且在各个系统里透传标记,从而达到追踪整个消息处理过程的能力。市面上大多数实现都是基于这一思想,可选方案的有很多,如 cat pip、Zipkin、Skywalkin,它们有需要代码注入的,有无注入的。在这里选用 Zipkin,Zipkin 需要在项目中加入一个库,并不需要写代码,这对业务的入侵做到了很少,非常方便。

在这里插入图片描述

  • 流量控制:
    • 到这里,这一切就完了吗?当然不是,微服务里还有一项非常重要的功能:流量控制还没有做。当海量的请求来临的时候,可以用增加容器数量的办法来提高服务能力,但是简单地添加实例是很危险的,因为整个系统的服务能力是被系统短板所限制的,简单地添加实例,并不是总能起到提高服务能力的作用。反而可能引起反作用,最终导致整个系统的崩溃。
    • 对整个系统的负载容量是有一个设计的,当超出设计的能力时,需要对多余的请求说 No。相应的方案分别是熔断、限流和降级。目前 Java 领域的这方面的 Hystrix,Sentinel 在这方面都做得很好。Sentinel 在阿里接受了考验,并且使用起来也很简单,所以选它。现在在整个系统里加上一个流量控中心,这样一个基本完整高可靠的系统就基本完成。

在这里插入图片描述

  • 在实际开发中,其实还有最关键的配置中心(Apollo),数据库(DB),缓存(Redis)等组件, 服务化网格, 可以把这些组件暂时放在 Kubernetes 之外,仍然是可以起到同样的效果。

二、微服务项目的具体实现

① 前端站点

  • 前端站点的逻辑很简单,就是显示一个页面,页面中有一个按键,当点击按键的时候,前端页面发起 ajax 请求,访问前端站点本身的一个接口,这个接口被 Nginx 代理,转发到 a.demo.com 微服务上,a. demo.com 微服务再将请求转发到 b. demo.com,b. demo.com 再将请求转发到 c. demo.com,最终将结果返回给前端,前端站点再将结果显示在页面上。通过结果显示,就能知道这次请求通过了那些服务器,每台服务器的服务运行时间大概是多少。
  • 前端站点代码大体如下:

在这里插入图片描述

  • 然后看 a、b、 c 应用部分的 Java 代码,这就是个普通的多模块 Maven 项目:

在这里插入图片描述

  • 项目很简单,分成了 3 个部分,一个是注册中心,也就是利用 Eureka 实现注册中心服务,另一个则是基础库项目,大部分功能都在这里实现,最后则是各个微服务项目,微服务项目只需要简单调用基础库就能完成。

② 注册中心

  • 注册中心的代码非常简单,只需要加一个简单的声明:

在这里插入图片描述

  • 这是注册中心的配置文件,在 Kubernetes 集群里运行时,可以运行 3 个节点组成高可用的注册中心集群,这时这个配置项需要相应的修改:

在这里插入图片描述

③ 基础库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 在基础库项目里,将很多的依赖都放在里面,这样应用项目只需要简单依赖基础库就可以,能够做到统一修改,同时也可以看到大部分依赖库只需要加入就可以,并不需编写代码就可以工作,这让开发工作变得轻松。

在这里插入图片描述

  • 对于微服务的返回结果,做一些美化格式,这样可以在检查结果时,比较容易:

在这里插入图片描述

  • 简单的定义了一些返回的结构,可以通过这些结构,微服务可以把处理时的时间戳,线程号,实例 IP 这些信息返回出来:

在这里插入图片描述

  • 基础模块的日志实现,从 GitHub 找的例子简单地进行了修改(这里只是简单实现,不要用于生产),这时,利用 logback.xml 的配置,可以把日志写入本地磁盘还是直接写入 Kafka:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • a.demo.com,b.demo.com,c.demo.com 应用实现:

在这里插入图片描述

  • 实现很简单,只是简单地调用基础库就可以了。注意每个应用需要实现一个探活接口 /hs,这样 Kubernetes 系统可以通过这个接口来探活,获知这个应用是不是准备好了,能不能接入流量,否则这个应用可能还在启动过程中,但是流量已经接入了,那么肯定会出问题。

在这里插入图片描述

  • 在每个应用的配置里,都预置了各个配置的项目,在本地运行的时候,可以填注入本地的配置,在 Kubernetes 里以容器形式进行运行,可以利用 yaml 来动态地修改它们,做到 2 种情况下完全兼容。

三、Kubernetes 的部署

  • 在完成应用的编写后,需要安装 Kubernetes 系统,如果已经有 Kubernetes 集群的,就可以直接跳过这个部分。除了 Kubernetes 集群以外,还需要 Prometheus and Grafana 这样的监控组件,因此这里推荐一个牛逼的安装工具,和所有现有的 Kubernetes 安装工具比,它是最好的,没有之一。
  • 它的名字是 K8seasy,它的优点在于:
    • 可以一键安装整体 Kubernetes 系统,无需了解任何背景知识;
    • 所有的镜像都已经内置,不会因为下载镜像失败而导致失败;
    • 安装支持各种不同版本 Kubernetes 版本;
    • 安装的服务是二进制版本的,非容器版本,稳定高效;
    • 支持安装 3 节点 高可用的生产环境集群。

① 安装过程

  • 下载 K8seasy:K8seasy 的官方主页;
  • K8seasy 的安装下载页:

在这里插入图片描述

  • 将 3 个安装文件都下载下来,其中 pack.2020.10.02.bin 和 installer 都是安装文件, kubernetes-server-linux-amd64.tar.gz 是 Kubernetes 的官方软件包,可以自己选择一个最新的版本。如果要选择一个其他版本的 Kubernetes:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 安装的过程很简单,2 条命令即可,这里假设需要安装 Kubernetes 的网络为 192.168.2.0,master 主机为 192.168.2.50。

② 创建密钥

sudo ./installer --genkey -hostlist=192.168.2.1

在这里插入图片描述

③ 创建集群

sudo ./installer   -kubernetestarfile kubernetes-server-linux-amd64v1.18.2.tar.gz -masterip 192.168.2.50
  • 稍等一会儿就能看到类似如下输出:

在这里插入图片描述

  • 就这么简单,一个 Kubernetes 已经装好了,此时相关的所有监控已经被完全安装好了。

④ 各项监控

  • 以 Master 节点为 192.168.2.50 为例,http://192.168.2.50:10000 可以直接打开 Dashboard,对整个集群有一个全面了解:

在这里插入图片描述

  • 打开 http://192.168.2.50:8080,可以直接访问 Alertmanager:

在这里插入图片描述

  • 打开 http://192.168.2.50:8081,可以直接使用 Grafana(用户 admin,密码 admin):

在这里插入图片描述
在这里插入图片描述

  • 打开 http://192.168.2.50:8082,可以访问 Prometheus:

在这里插入图片描述

⑤ 多套环境监控

  • 为了支持多集群管理,再推荐一个工具,刚才说到直接使用 http://192.168.2.50:1000 这个页面可以直接管理整个集群,但是在公司里如果有多个集群,该如何管理呢?别担心,K8seasy 已经有对应的解决方案。

在这里插入图片描述

  • 仔细看刚才的安装好的日志,里面提示专门生产了一个 lens.kubeconfig 的配置文件,并且有一个域名和 IP 的对应表。这时候,只需要首先在本地 Host 文件里加入这个对应:

在这里插入图片描述

  • 然后去 https://Kuberneteslens.dev/:

在这里插入图片描述

  • 下载一个 Lens 的安装包,安装 Lens 以后,只需要将 lens.kubeconfig 导入到 Lens 里:

在这里插入图片描述

  • 导入完成后,就可以远程管理这个集群了,这样有多个集群,也可以只用一套 Lens 进行管理,Lens 的界面优美,使用方便。

在这里插入图片描述

  • 好了,Kubernetes 的安装完成,当然了 K8seasy 的功能是非常强大的,可以用 sudo ./installer -h 查看帮助, 也可以使用 sudo ./installer -demo 查看各种场景的安装帮助:

在这里插入图片描述

四、微服务高可用部署及验证

① 服务部署上去

  • 依次运行每条部署 Yaml 的命令即可,不需要做其他的操作。
  • 注意,镜像在 Docker-Hub,可能需要一定时间才能下载。
  • 运行后在 Dashboard 查看,你可以看到类似的信息,所有的服务都已经成功运行。

② 查看 Dashboard

在这里插入图片描述

  • 此时修改本地的 Hosts:

在这里插入图片描述

  • 这样的话,因为 Kubernetes 是支持 nginx-ingress 的,因此可以直接访问 Master 的物理 IP 来访问这些服务,不需要做任何转换。
  • 首先可以打开 Dashboard 从中查到 Eureka,服务器的具体 IP,然后访问 Eurka 服务。

③ 查看注册中心

  • 在页面中可以发现,在 Kubernetes 集群里,启动 3 个 Eureka 服务,它们相互注册,组成了一个高可用集群:

在这里插入图片描述

  • 其次,在 Grafana 中导入 JVM 的监控项目:

在这里插入图片描述

  • 这样 Grafana 可以把各个 Java 服务的具体状态做一个收集,完成我们需要的监控。

④ 前端验证

  • 此时,打开 http://www.demo.com 的网页,可以点击页面上的 get 请求按键,模拟发出请求,随后就会发现页面里显示出的信息在不断变化:

在这里插入图片描述

  • 在页面显示的内容里,可以清楚地发现,消息在不同实例里处理,如果有一个实例出现了故障是不会影响我们现在的业务的:

在这里插入图片描述

⑤ 模拟验证

  • 使用一个简单的脚本,模拟每 3 秒从前端访问一次后端:

在这里插入图片描述

⑥ 调用关系验证

  • 首先打开 Zipkin:zipkin.demo.com:

在这里插入图片描述

  • 点击具体的请求,可以查看到每次请求在内部的细节:

在这里插入图片描述

⑦ 限流熔断验证

  • 打开 Sentinel 站点,这个站点可以监控,也可以对微服务进行限流,限速,熔断等操作(密码口令都是 Sentinel):

在这里插入图片描述

  • 进入控制台后,可以发现所有的服务已经自动被发现,并存在于左边的菜单:

在这里插入图片描述

  • 分别点开 a、b、c,3 个服务,可以看到规律的周期访问,和脚本的测试速度是一致的:

在这里插入图片描述

⑧ 应用状态验证

  • 打开 Grafana 的监控页,可以查看所有应用的状态,包括 heap 大小,启动时间,错误数目等:

在这里插入图片描述

  • 通过这张图可以了解每个应用本身的状态,使用了多少内存,响应的代码是多少,JVM 使用情况。相信此时已经对各个组件的情况,监控都有了一个全面了解,一个基于 Kubernetes 的微服务架构已经开始工作。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245638.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea中定时+多数据源配置

因项目要求,需要定时从达梦数据库中取数据,并插入或更新到ORACLE数据库中 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-…

多架构容器镜像构建实战

最近在一个国产化项目中遇到了这样一个场景&#xff0c;在同一个 Kubernetes 集群中的节点是混合架构的&#xff0c;也就是说&#xff0c;其中某些节点的 CPU 架构是 x86 的&#xff0c;而另一些节点是 ARM 的。为了让我们的镜像在这样的环境下运行&#xff0c;一种最简单的做法…

react+datav+echarts实现可视化数据大屏

&#x1f4d3;最近有点闲&#xff0c;就学习了下react&#xff0c;没想到就把react学完了&#xff0c;觉得还不错&#xff0c;就打算出一把reactdatav的简易版可视化数据大屏供大家做个参考。 &#x1f4d3;效果如下 1下载必要的框架 &#x1f4d3; react路由 npm install re…

0-50KHz频率响应模拟量高速信号隔离变送器

0-50KHz频率响应模拟量高速信号隔离变送器 型号&#xff1a;JSD TA-2322F系列 高速响应时间&#xff0c;频率响应时间快 特点&#xff1a; ◆小体积,低成本,标准 DIN35mm 导轨安装方式 ◆六端隔离(输入、输出、工作电源和通道间相互隔离) ◆高速信号采集 (-3dB,Min≤ 3.5 uS,订…

【Qt5】ui文件最后会变成头文件

2023年12月14日&#xff0c;周四下午 我也是今天下午偶然间发现这个的 在使用Qt的uic&#xff08;User Interface Compiler&#xff09;工具编译ui文件时&#xff0c;会生成对应的头文件。 在Qt中&#xff0c;ui文件是用于描述用户界面的XML文件&#xff0c;而头文件是用于在…

【JUC】二十九、synchronized锁升级之轻量锁与重量锁

文章目录 1、轻量锁2、轻量锁的作用3、轻量锁的加锁和释放4、轻量级锁的代码演示5、重量级锁6、重量级锁的原理7、锁升级和hashcode的关系8、锁升级和hashcode关系的代码证明9、synchronized锁升级的总结10、JIT编译器对锁的优化&#xff1a;锁消除和锁粗化11、结语 &#x1f4…

保障网络安全:了解威胁检测和风险评分的重要性

在当今数字时代&#xff0c;网络安全问题变得愈发突出&#xff0c;而及时发现和迅速应对潜在威胁成为保障组织信息安全的首要任务。令人震惊的是&#xff0c;根据2023年的数据&#xff0c;平均而言&#xff0c;检测到一次网络入侵的时间竟然长达207天。这引起了对安全策略和技术…

MPLS专线和互联网专线有什么区别?如何选择?

MPLS和互联网专线是什么&#xff1f; MPLS专线和互联网专线是企业网络连接的常见方式。MPLS专线基于多协议标签交换&#xff08;MPLS&#xff09;该技术利用专线连接两个或多个分支机构&#xff0c;提供高质量的数据传输服务。互联网专线是基于公共知识产权基础设施的连接方式…

Python实现高效摸鱼,批量识别银行卡号并自动写入Excel表格

前言 每当有新员工入职&#xff0c;人事小姐姐都要收集大量的工资卡信息&#xff0c;并且生成Excel文档&#xff0c;看到小姐姐这么辛苦&#xff0c;我就忍不住要去帮她了… 于是我用1行代码就实现了自动识别银行卡信息并且自动生成Excel文件&#xff0c;小姐姐当场就亮眼汪汪…

ChatGPT一周年,一图总结2023生成式AI里程碑大事件时间线

带你探索AI的无限可能&#xff01;AI一日&#xff0c;人间一年&#xff0c;这句话绝非空谈&#xff01; AI技术在不断地发展&#xff0c;让我们一起期待它未来更多的可能性吧&#xff01; 2022 年 11 月 30 日&#xff0c;OpenAI 宣布正式推出 ChatGPT。365 天过去&#xff0c;…

羊大师解读提高免疫力,能从羊奶开始吗?

羊大师解读提高免疫力&#xff0c;能从羊奶开始吗&#xff1f; 在当今充满挑战的世界中&#xff0c;拥有强大的免疫力是保持健康的关键。免疫系统是我们身体的守护者&#xff0c;能够抵御病菌和疾病&#xff0c;使我们远离健康问题。而如何提高免疫力一直是人们关注的焦点。近…

‘BLEUUID‘ does not name a type错误怎么解决?

摘要&#xff1a;arduino环境下对esp32蓝牙编程时会遇到BLEUUID does not name a type错误&#xff0c;本文介绍解决方法。 硬件设备是安信可ESP32-S模组。 错误发生在代码最开始的地方&#xff0c;include了一个蓝牙设备头文件&#xff0c;然后定义了UUID&#xff0c;注意看&a…

Java序列化、反序列化-为什么要使用序列化?Serializable接口的作用?

什么是序列化和反序列化&#xff1f; 把对象转换成字节序列把字节序列恢复成对象 结合OSI七层协议模型&#xff0c;序列化和反序列化是在那一层做的&#xff1f; 在OSI七层模型中&#xff0c;序列化工作的层级是表示层。这一层的主要功能包括把应用层的对象转换成一段连续的二进…

Vue3-18-侦听器watch()、watchEffect() 的基本使用

什么是侦听器 个人理解&#xff1a;当有一个响应式状态&#xff08;普通变量 or 一个响应式对象&#xff09;发生改变时&#xff0c;我们希望监听到这个改变&#xff0c;并且能够进行一些逻辑处理。那么侦听器就是来帮助我们实现这个功能的。侦听器 其实就是两个函数&#xff…

JAVA 版多商家入驻 直播带货 商城系统 B2B2C 之 鸿鹄云商B2B2C产品概述

随着互联网的快速发展&#xff0c;越来越多的企业开始注重数字化转型&#xff0c;以提升自身的竞争力和运营效率。在这个背景下&#xff0c;鸿鹄云商SAAS云产品应运而生&#xff0c;为企业提供了一种简单、高效、安全的数字化解决方案。 鸿鹄云商SAAS云产品是一种基于云计算的软…

Seata配置

参考教程 seata 分布式事务的环境搭建与使用 Seata 1.4.0 nacos配置和使用&#xff0c;超详细 Seata 1.4.2 的安装 Nacos的配置和使用 官网下载地址 本文以v1.4.1为例 1.数据库及表的创建 创建seata数据库&#xff0c;创建以下表&#xff08;右键连接-》新建数据库seata-》…

一文读懂FastAPI:Python 开发者的福音

FastAPI是一个基于Python的现代化Web框架&#xff0c;它提供了快速、简单和高性能的方式来构建API。 它结合了Python的静态类型检查和自动化文档生成的功能&#xff0c;使得开发API变得更加容易和高效。 下面将介绍如何使用FastAPI快速开发接口&#xff0c;并且利用自动生成的…

leetcode做题笔记2132. 用邮票贴满网格图

给你一个 m x n 的二进制矩阵 grid &#xff0c;每个格子要么为 0 &#xff08;空&#xff09;要么为 1 &#xff08;被占据&#xff09;。 给你邮票的尺寸为 stampHeight x stampWidth 。我们想将邮票贴进二进制矩阵中&#xff0c;且满足以下 限制 和 要求 &#xff1a; 覆盖…

OpenKylin安装idea

Web和客户端都支持Linux了&#xff0c;一方面为了Linux上调试程序方便&#xff0c;另一方面为了把开发环境彻底支持Linux&#xff0c;在Linux上安装idea运行代码&#xff0c;之前剔除Maven那些的优点就来了&#xff0c;在OpenKylin上我只要安装idea和jdk就能正常运行代码了。最…

【c】数组元素移动

本题的难点之处就是不让你创建新的数组&#xff0c;而且移动的距离也没有给限制&#xff0c;比如有7个数&#xff0c;本题没有限制必须移动距离小于7&#xff0c;也可能移动的距离大于7&#xff0c;甚至更多&#xff0c;下面附上我的代码 #include<stdio.h>int main() {…