Ubuntu+Apache2 搭建Gerrit 环境

一、前言

时隔多年,好久没有更新CSDN 博客了,主要原因有如下两点:

1、平时工作繁忙,无暇更新。

2、工作内容涉及信息安全,一些工作经验积累不便更新到互联网上。

  最近一直在折腾搭建Gerrit 环境,最开始是在Windows 环境下尝试搭建的,搭建不成功,遇到很多问题,并且网上Windows 环境下资料和文章较少,所以尝试在ubuntu 环境下搭建。

  也折腾了挺长时间的,期间查阅了大量的CSDN 博文,终于调试ok,CSDN 上关于的搭建apache + unbuntu 搭建Gerrit 的博客挺多的,但大多比较零散,针对遇到的问题,讲解不够透彻,很多点网上只是说要这么配置,但并没有说为什么要这么配置,自己也尝试了很多博客的方法终于搭建成功,很想总结分享给大家。

二、搭建环境说明

平台:VMware® Workstation 17 Pro

系统:elementary OS 5.0 Juno(Ubuntu 7.3.0-16ubuntu3))

Apache 版本号: Apache/2.4.29 (Ubuntu)

Gerrit 版本号:gerrit-3.1.3

   强烈推荐搭建按照这篇博客进行配置,个人感觉这篇文章是CSDN 上写的比较好的,里面各种方法也都是我这边踩过的坑,遇到的问题,并且按照这篇文章进行解决的:

【Git】Ubuntu18.04搭建gerrit+gitweb+apache2服务器_ubuntu 搭建git gerrit服务器-CSDN博客

https://blog.csdn.net/u010440719/article/details/127704664

三、安装过程遇到的问题

  具体的安装Apache 和Gerrit 的方法,网上这类文章很多,就不再这里赘述了,各位可以自己搜索相关文章,这里主要讨论安装过程中遇到的问题,避免大家走弯路。

  安装Gerrit 的方式很简单,直接去对应的网址上下载最新的Gerrit 版本安装即可,安装命令也很简单,一条命令即可:

java -jar gerrit-3.9.1.war init -d ~/review_site

  这里的-d 参数是指定gerrit 初始化安装的目录,执行后安装过程中会让你选择很多参数,大部分参数都不重要,因为你最终都可以在安装完成的gerrit.config 文件中重新修改,这里需要注意的是,Gerrit 的认证方式要改成HTTP,不要选择openid(默认是openid),原因接下来会讲到。

sudo  vim /home/gerrit/review_site/etc/gerrit.config

1、Gerrit 的两种认证方式:

(1)OpenId:在安装完成Gerrit,登录Gerrit 之前需要有一个用户认证,默认就是open id,这种方式我们尝试了很久,各种注册Ubuntu 账号,最终还是不行,不得已尝试第2种方式:Apache 反向代理的方式

(2)Apcahe 反向代理:刚开始我也不懂什么叫做Apache 反向代理,只是一股脑的按照网上的各种教程配置,最终发现还是不行,踩了很多的坑。

  所谓Apache 的反向代理就是,Gerrit 会运行在一个IP地址的一个端口上,比如是192.168.170.129:8092,这个时候Gerrit 会监听192.168.170.129 地址上8092 端口上的访问请求,Apache 默认运运行的端口是80 和8080,它会监听这个端口上的访问请求;

  按理说我们配置运行完Gerrit 后直接访问192.168.170.129:8092 端口就好了,但是,因为我们使用的Apache 反向代理做为Gerrit 首次登录认证的一种的方式,那么我们就不能直接通过192.168.170.129:8092 端口去登录Gerrit 了,我们就必须使用Apache 去作为我们登录Gerrit 的一种认证方式,让Apache 去对登录的用户做一个认证。

  这个时候我们就需要用Apache 做反向代理,那么什么是反向代理呢,直白点就是,当你访问这个地址时,它会代理到另外一个地址。这里说的清除点就是,当你访问Apache 的8080 端口时,它会帮你代理代理到Gerrit 的8092 端口,这样的话,你访问192.168.170.129:8080 地址实际上就是访问的192.168.170.129:8092,这个就是Apache 的反向代理。

  那么回到开始的,Gerrit 的Apache 反向代理认证,因为我们做了用Apache 对Gerrit 做了反向代理,并且也通过Apache 对Gerrit 做认证,那么在通过Apache 的8080 端口访问Gerrit 时,Gerrit 就会要求,Apache 的代理请求中带上Gerrit 的认证信息,如果没有带Gerrit 就会拒绝访问,就会出现如下的Gerrit 报错:

就是这个报错,相信大家也深受这个报错的折磨,我有折腾了好久好久,按照网上的方法尝试了很多次都不行,这个其实就是Apache 反向代理配置的问题。

出现这个问题的原因主要有:

(1)Apache 反向代理不生效:

相信大家刚开始的时候都会按照网上的方法

sudo apt-get install apache2
cd /etc/apache2
创建httpd.conf
sudo touch /etc/apache2/httpd.conf
sudo vim httpd.conf
文件写入以下内容:

通过httpd.conf 去配置Apache 反向代理,但是不知道时我的原因,还是本身这种方法就不对,这个文件中配置一直就不生效,所以折腾了很久,改了很多参数,一点用都没有。

后来,参考这篇文章才找到配置生效的地方:/etc/apache2/sites-available/my-default.conf

这里就不在赘述了,可以直接参考下面的这篇文章,已经讲的很清楚了。

Linux中配置Gerrit的apache2反向代理_gerrit apache-CSDN博客

https://blog.csdn.net/m0_48465029/article/details/137328385

然后直接在新建的这个/etc/apache2/sites-available/my-default.conf 文件中配置Apache 反向代理就好了。

  配置完直接重启Apache 服务就好了,推荐大家用下面的命令:

sudo /etc/init.d/apache2 restart

  重启过程中可能会有一些报错导致Apache 运行不起来,这是个好消息,至少说明你配置的地方是对,说明你方向是对的。

  报错原因大家可以直接查看Apache 的日志文件。

sudo vim /var/log/apache2/error.log

sudo vim /var/log/apache2/other_vhosts_access.log

sudo vim /var/log/apache2/access.log

主要看error.log 就可以了,我这边遇到的第一个问题就是没有添加Apache 代理的依赖库文件:

这里可以参考这篇文章:

AH01177: Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??-CSDN博客

https://blog.csdn.net/zhaojigao/article/details/86641824

 添加依赖的so 库文件,按照这个文章的描述操作就可以了。

主要是添加这三个依赖文件,然后按照命令操作下就可以了:

gerrit1@pc:/etc/apache2$ grep -rn slotmem_shm_module  ./
./mods-available/slotmem_shm.load:1:LoadModule slotmem_shm_module /usr/lib/apache2/modules/mod_slotmem_shm.so
gerrit1@pc:/etc/apache2$ 
gerrit1@pc:/etc/apache2$ sudo ln -s /etc/apache2/mods-available/slotmem_shm.load /etc/apache2/mods-enabled/slotmem_shm.load
gerrit1@pc:/etc/apache2$ 
gerrit1@pc:/etc/apache2$ sudo /etc/init.d/apache2 restart
 * Restarting web server apache2
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
   ...done.
gerrit1@pc:/etc/apache2$

这里解决了反向代理基本上就没问题了,然后就是解决各种报错就好了,Apache 各种报错原因及解决办法网上有很多的文章。

因为使用的是Apache 的反向代理,那么这里首先就好看下Apache 监听的是哪些端口:

这里可以用这个命令查看:

wangpeng@linux:~$ sudo netstat -tulnp | grep apache
[sudo] wangpeng 的密码:       
tcp6       0      0 :::8080                 :::*                    LISTEN      916/apache2         
tcp6       0      0 :::80                   :::*                    LISTEN      916/apache2         
wangpeng@linux:~$

可以看到Apache 主要监听的8080 和80 端口,这里我也尝试给Apache 添加一个新的端口,通过这个端口去做Gerrit 反向代理,但是发现不太行,添加不上去,于是就放弃了,还是使用Apache 原本监听的8080 和80 端口,因为Apache 默认就监听的这两端口,也不用自己新加了,直接用就好了,我选用的是8080 端口,80 默认是系统保留的端口,所以尽量选用大一点的端口号,一般不会被系统占用。

那么接下来就是配置上面说的新建的这个/etc/apache2/sites-available/my-default.conf 文件,添加一个新的虚拟主机,这里大家可以直接参考我的配置:

<VirtualHost *:8080>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf

    ServerName localhost:8080

    ProxyRequests off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
          Order deny,allow
          Allow from all
    </Proxy>

    <Location "/login/">
        AuthType Basic
        AuthName "WP Gerrit Code Review"
        Require valid-user
        AuthBasicProvider file
        AuthUserFile /home/gerrit/review_site/passwords
        #这个路径是gerrit账户密码管理,后续的步骤中会创建此文件。路径有写正确
    </Location>

    AllowEncodedSlashes On

    ProxyPass / http://192.168.170.129:8092/
    ProxyPassReverse / http://192.168.170.129:8092/
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

这里也有坑,需要注意这里的端口号<VirtualHost *:8080>,也要改成8080

这里配置好了之后基本上代理就没啥问题了。

上面说到配置代码的目的是为了让Apache 对Gerrit 做认证,就这里的

AuthBasicProvider file
AuthUserFile /home/gerrit/review_site/passwords

这里要新建两个用户,并配置密码,用户和密码的密文存在AuthUserFile /home/gerrit/review_site/passwords 文件中,配置密码的方式大家可以在网上查找,最终配置生效后大家可以看下/home/gerrit/review_site/passwords 文件中的密码信息。

配置完成后重启Apache 服务让配置生效,大家也可以使用命令查看Apache 服务器的运行情况:

sudo systemctl status apache2.service

只有变成绿色的才代表Apache 运行成功了。

(2)gerrit.config 配置的问题

至此Apache 的反向代理就弄好了,接下来就是配置/home/gerrit/review_site/etc/gerrit.config 文件,我的配置如下:

[gerrit]
	basePath = git
	canonicalWebUrl = http://192.168.170.129:8092
	serverId = **********************************
[container]
	javaOptions = "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"
	javaOptions = "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance"
	user = gerrit
	javaHome = /usr/lib/jvm/java-11-openjdk-amd64
[database]
    type = mysql
    hostname = localhost
    database = reviewdb
    username = gerrit
[index]
	type = lucene
[auth]
	type = HTTP
[receive]
	enableSignedPush = true
[sendemail]
    enable = true
    smtpServer = smtp.qq.com
    smtpServerPort = 465
    smtpEncryption = SSL
    sslVerify = true
    smtpUser = *********@qq.com
    from = *********@qq.com
[sshd]
	listenAddress = *:29418
[httpd]
	listenUrl = proxy-http://192.168.170.129:8092/
[cache]
	directory = cache

这个文件没有啥配置的,按照网上的抄就行了,需要主要的是这里配置的是Gerrit 的网址和端口,需要和Apache 代理的网址和端口一致,并且这里的Gerrit 的端口不要和Apache 的端口8080 配成一样的,我这里配置的8092

这里配置完了之后,重启Gerrit 服务就可以生效了:

sudo /home/gerrit/review_site/bin/gerrit.sh stop

sudo /home/gerrit/review_site/bin/gerrit.sh run

如果一切顺利的话,到这里Gerrit 就可以登录上了

​​​​​​​2、Gerrit SMTP 邮箱配置

  接下来就是配置Gerrit 的SMTP 邮箱服务了,因为Gerrit 必须要认证邮箱,才可以push 代码,SMTP 配置也是在/home/gerrit/review_site/etc/gerrit.config 文件中,

  首先给大家说下为什么要配置SMTP 邮箱,这里是因为,gerrit 登录上如果想要提交代码或者新建项目都是必须要做验证登录用户的邮箱的,否则你是不能提交代码的。

  要验证用户邮箱,就需要你把Gerrit 的SMTP 邮箱配置ok,这样你的Gerrit 才可以发送验证邮件给你完成验证。

这里大家可以参考这篇文章:

gerrit服务器邮箱设置(三)_gerrit邮箱配置-CSDN博客

https://blog.csdn.net/sevenjoin/article/details/118189159

需要注意的是:

1、建议大家把密码写在这个文件中:/home/gerrit/review_site/etc/secure.config

2、主要注意这里的enable、smtpServer、smtpServerPort、smtpUser 等等字段的顺序必须按照,否则在Gerrit 上点击Send 验证邮件的时候会各种奇奇怪怪的错。

 这里大家直接Copy 我的配置即可:

[sendemail]
    enable = true
    smtpServer = smtp.qq.com
    smtpServerPort = 465
    smtpEncryption = SSL
    sslVerify = true
    smtpUser = *******@qq.com
    from = *******@qq.com

3、虚拟机的ip 地址固定

  虚拟机的IP 地址固定:这个是因为我们是在虚拟机上配置的,虚拟机的IP 地址默认是DHCP 动态分配,这样当你重启虚拟机,或者隔几天重新打开虚拟机,虚拟机的IP 地址会变化,这样就会导致之前配置的Apache 反向代理的IP 地址失效,Apche 和Gerrit 的IP 地址匹配不上,会导致Apache 反向代理失效,解决办法就是固定虚拟机的IP 地址。

  这个我网上搜索了很多教程,配置都相对比较复杂,这里给给大家推荐一个简单的方法。

  首先找到VM 虚拟机安装的位置,找到vmnetcfg.exe,打开DHCP,将起始IP 地址和结束IP 地址的范围改成很小的一个范围,因为我这边Apache 反向代理中配置的IP 地址是192.168.170.129,所以我这边就显示IP范围是129~130,并且将最长租用时间默认租用时间都改为最长,这样配置完之后,基本上每次DHCP 分配下来的IP 地址就都是192.168.170.129 了,也就相当于是固定了虚拟机IP地址了,哈哈。

4、Gerrit 新建项目

  这里也是一条命令即可,这条命令是新建一个Test 的项目

ssh -p 29418 gerrit@192.168.170.129 gerrit create-project --owner gerrit --empty-commit "Test"

5、添加Gerrit的Verify Label

  为啥要添加这Verify Label,这是因为,当你新建Gerrit 项目想要提交代码入库时,必须要Verify +1 才能入库,Gerrit 这边默认是需要配置Jenkins 环境,当你提交代码后会触发代码门禁,Jenkins 构建pass 后会自动Verify +1,所以Gerrit 默认Verify Label 是没有权限编辑的,就会造成提交无法Merge,那么下面我们来看看怎么解决这个问题。

  这里也给大家推荐一篇文章:

gerrit新增code-reviewer label - 简书

https://www.jianshu.com/p/0df832fcf04f

  基本上按照这篇文章配置就好了,不过这里面也有坑,需要在Gerrit 的refs/head/* 下面打开Submit 权限,这样才可以git push 将修改push 上去,具体的大家碰到了网上搜搜文章就可以解决了。

git push  origin HEAD:refs/meta/config

未完待续。。

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

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

相关文章

PHP 超级全局变量详解

在PHP编程中&#xff0c;超级全局变量&#xff08;Super Global Variables&#xff09;是一种特殊的变量&#xff0c;可以在脚本的任何地方访问&#xff0c;而不受作用域限制。它们被设计用于在不同的脚本文件、函数和类之间共享数据&#xff0c;是PHP语言中非常重要和实用的特…

GPU设置

GPU降温测试 前提 同一个训练程序&#xff0c;使用8块GPU&#xff0c;GPU使用率基本全程>90%&#xff0c;GPU为1080 Ti 限制最高功率效果 不限制最高功率(默认最高功率250W)&#xff1a;最高温度85&#xff0c;大多时间在75-85之间 将最高功率限制为150W&#xff1a;最高…

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering 一、前言Abstract1 INTRODUCTION2 RELATED WORK2.1 Traditional Scene Reconstruction and Rendering2.2 Neural Rendering and Radiance Fields2.3 Point-Based Rendering and Radiance Fields 3 O…

新手向导:掌握Axure RP的第一步

其实很多时候&#xff0c;我们很容易把教程做得太复杂&#xff0c;让学生失去重点被复杂的理论吓到。入门基础的时候只需要先弄清楚两个核心内容&#xff0c;学起来就容易多了:一是简单了解这个软件&#xff0c;二是学习这个软件的基本操作。所以如果你问我什么是好的 Axure RP…

python中pip换源

目录 1. 背景2. Python 的 pip 换源2.1 临时换源&#xff08;命令行中使用参数&#xff09;2.2 永久换源&#xff08;修改配置文件&#xff09;2.2.1 Windows系统2.2.2 Linux/macOS系统 2.3 使用 pip-config 命令换源&#xff08;Linux/macOS 特定&#xff09; 3. 常用的 PyPI …

U盘数据被删,四个补救措施要收藏好!

在日常工作及学习过程中&#xff0c;大家都会频繁使用U盘进行数据储存与转移。然而因操作失误&#xff0c;如&#xff1a;手动误删、直接清空或格式化等&#xff0c;将会造成一些重要的数据遗失&#xff0c;并且在面临此状况时&#xff0c;就需要找到一个有效的方法去恢复了。那…

C语言分支和循环(上)

C语言分支和循环&#xff08;上&#xff09; 1. if语句1.1 if1.2 else1.3 分支中包含多条语句1.4 嵌套if1.5 悬空else问题 2. 关系操作符3. 条件操作符4. 逻辑操作符&#xff1a;&&,||,&#xff01;4.1 逻辑取反运算符4.2 与运算符4.3 或运算符4.4 练习&#xff1a;闰年…

GRS认证流程是什么?

GRS认证的认证流程主要包括以下几个步骤&#xff1a; 1. 提交申请 首先&#xff0c;企业需要向GRS认证机构提交认证申请&#xff0c;并提供相关的企业信息和产品信息。这通常包括企业的基本信息、生产工厂信息、产品范围、生产流程等。 2. 合同评审 认证机构会对企业提交的…

【php】【mysql】【layui】 原生初级简易留言簿系统成品代码动态网站开发网页WEB浏览器端B/S结构

更多项目点击&#x1f446;&#x1f446;&#x1f446;完整项目成品专栏 【php】【mysql】【layui】 原生初级简易留言簿系统成品代码动态网站开发网页WEB浏览器端B/S结构 获取源码方式项目说明&#xff1a;文件包含&#xff1a;项目运行环境项目运行截图 获取源码方式 加Q群…

如何快捷批量处理图片?图片批量改大小、格式、尺寸的方法

怎么把图片批量修改成同一尺寸呢&#xff1f;图片在日常工作和生活中有很多的用途&#xff0c;每天都会需要使用不同类型的图片来获取我们需要的内容。在使用图片的时候&#xff0c;经常会遇到比较常见的几个限制问题&#xff0c;比如图片大小、图片尺寸、图片格式等&#xff0…

Google发布Gemma 2轻量级开放模型 以极小的成本提供强大的性能

除了 Gemini 系列人工智能模型外&#xff0c;Google还提供 Gemma 系列轻量级开放模型。今天&#xff0c;他们发布了 Gemma 2&#xff0c;这是基于全新架构设计的下一代产品&#xff0c;具有突破性的性能和效率。 Gemma 2 有两种规格&#xff1a;90 亿 (9B) 和 270 亿 (27B) 个参…

ElasticSearch中的BM25算法实现原理及应用分析

文章目录 一、引言二、BM25算法实现原理BM25算法的实现原理1. 词频&#xff08;TF&#xff09;&#xff1a;2. 逆文档频率&#xff08;IDF&#xff09;&#xff1a;3. 长度归一化&#xff1a;4. BM25评分公式&#xff1a; BM25算法示例 三、BM25算法在ElasticSearch中的应用分析…

MTK8786/MT8786芯片性能参数_规格书_datasheet

联发科MT8786(MTK8786)处理器采用了台积电12纳米FinFET技术&#xff0c;由2个Cortex A75核心和6个Cortex A55核心组成&#xff0c;其中大核A75主频为2.0GHz&#xff0c;GPU采用了ARM Mali-G52。MTK8786芯片设计极大地提升了智能设备的性能和安全等级。 MT8786采用了安全的ISP设…

AI数据分析003:用kimi生成一个正弦波数学动画

文章目录 一、正弦波公式二、输入内容三、输出内容一、正弦波公式 ƒ(x) = a * sin(x + x0) + b 公式中: a: 决定正弦函数振动幅度的大小; x0:表示x开始比0拖后的弧度值; b:表示函数偏离X轴的距离; 对于难以理解的学生来说,可以用动画把这个公式直观的展现出来。 二…

中小企业在数字化转型过程中遇到的挑战有哪些?

引言&#xff1a;中小企业推进数字化转型的背景是多重因素叠加的结果&#xff0c;包括市场竞争压力、信息技术发展及普及、各级政府政策支持及引导、企业经营发展需求和人才结构变化等。这些因素共同推动了中小企业加快数字化转型的步伐&#xff0c;以应对日益复杂多变的市场环…

通讯录项目的实现(基于顺序表)

前言 建议先看顺序表&#xff08;上卷&#xff09;、顺序表&#xff08;下卷&#xff09;&#xff0c;再来看本篇。 思路 通讯录就是由一条条联系人数据组成的。在一条联系人数据中会有一些相关信息&#xff1a;姓名、性别、年龄、电话、住址等。 在“顺序表&#xff08;上卷…

多模态语言模型的新突破:Reka Core、Flash和Edge系列

人工智能领域的每一次技术革新都可能引领一场行业的变革&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;多模态语言模型&#xff08;MLMs&#xff09;正逐渐成为推动智能系统发展的核心力量。Reka团队最新推出的Reka Core、Flash和Edge系列模型&…

Educational Codeforces Round 112 (Rated for Div. 2) C. Coin Rows(构造 + 贪心 + 前缀和)

可以知道爱丽丝的路径是拐两次弯的折线 那么我们知道鲍勃能够选择的位置只有两段黄线中的一段 所以可以求出来第二行的后缀和&#xff0c;然后求出来第一行的前缀行&#xff0c;这样鲍勃在爱丽丝分割之后的情况下就会选择这两者中最大的一段&#xff0c;然而爱丽丝也会阻碍鲍…

浅谈LiveData的通知过程

浅谈 LiveData 的通知机制 LiveData 和 ViewModel 一起是 Google 官方的 MVVM 架构的一个组成部分。巧了&#xff0c;昨天分析了一个问题是 ViewModel 的生命周期导致的。今天又遇到了一个问题是 LiveData 通知导致的。而 ViewModel 的生命周期和 LiveData 的通知机制是它们的…

c++习题03-分卡片

目录 一&#xff0c;题目 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;题目 二&#xff0c;思路 在做题的时候一定要认真审题&#xff0c;抓住关键的点和条件&#xff0c;才能够更高效的做对题目。 上面的题目有以下关键点&#xff08;关键条件&#xff0…