前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CentOS7搭建ELK-6.2.3版本

CentOS7搭建ELK-6.2.3版本

作者头像
程序员欣宸
发布于 2022-05-09 01:12:23
发布于 2022-05-09 01:12:23
53100
代码可运行
举报
文章被收录于专栏:实战docker实战docker
运行总次数:0
代码可运行

ELK是ElasticSerach、Logstash、Kibana三款产品名称的首字母集合,用于日志的搜集和搜索,今天我们一起搭建和体验基于ELK的日志服务

环境规划

本次实战需要两台电脑(或者vmware下的两个虚拟机),操作系统都是CentOS7,它们的身份、配置、地址等信息如下:

hostname

IP地址

身份

配置

elk-server

192.168.119.132

ELK服务端,接收日志,提供日志搜索服务

双核,4G内存

nginx-server

192.168.119.133

Nginx服务端,产生的访问日志通过上报到Logstash

双核,2G内存

部署情况简介

运行时的部署情况如下图所示:

  1. 业务请求到达nginx-server机器上的Nginx;
  2. Nginx响应请求,并在access.log文件中增加访问记录;
  3. FileBeat搜集新增的日志,通过LogStash的5044端口上传日志;
  4. LogStash将日志信息通过本机的9200端口传入到ElasticSerach;
  5. 搜索日志的用户通过浏览器访问Kibana,服务器端口是5601;
  6. Kibana通过9200端口访问ElasticSerach;

关于Nginx安装

请在nginx-server机器上安装nginx1.10.1或者更高版本,安装的详细步骤请参考《 CentOS7安装Nginx1.10.1》

接下来安装ELK吧;

安装JDK

首先请在elk-server机器上JDK8;

在ELK官方文档中(https://www.elastic.co/guide/en/elasticsearch/hadoop/6.2/requirements.html),推荐的JDK版本为8,如下图所示:

在CentOS7安装JDK8的步骤请参考《CentOS7安装JDK8》

创建用户

ElasticSerach要求以非root身份启动,所以我们要创建一个用户:

  1. 创建用户组:groupadd elasticsearch;
  2. 创建用户加入用户组:useradd elasticsearch -g elasticsearch;
  3. 设置ElasticSerach文件夹为用户elasticsearch所有:chown -R elasticsearch.elasticsearch /usr/local/work/elasticsearch-6.2.3;

系统设置

  1. 设置hostname,打开文件/etc/hostname,将内容改为elk-server
  2. 关闭防火墙(如果因为其他原因不能关闭防火墙,也请不要禁止80端口):systemctl stop firewalld.service
  3. 禁止防火墙自动启动:systemctl disable firewalld.service
  4. 打开文件/etc/security/limits.conf,添加下面四行内容:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
  1. 打开文件/etc/sysctl.conf,添加下面一行内容:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vm.max_map_count=655360
  1. 加载sysctl配置,执行命令:sysctl -p
  2. 重启电脑;

elk-server:安装文件准备

请在ELK官网https://www.elastic.co/downloads下载以下文件:

  1. elasticsearch-6.2.3.tar.gz;
  2. logstash-6.2.3.tar.gz;
  3. kibana-6.2.3-linux-x86_64.tar.gz;

上述三个文件,推荐在CentOS7的命令行输入以下四个命令下载:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.3.tar.gz
wget https://artifacts.elastic.co/downloads/logstash/logstash-6.2.3.tar.gz
wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.3-linux-x86_64.tar.gz

下载完毕后,创建目录/usr/local/work,将刚刚下载的三个文件全部在这个目录下解压,得到以下三个文件夹:

  1. /usr/local/work/elasticsearch-6.2.3
  2. /usr/local/work/logstash-6.2.3
  3. kibana-6.2.3-linux-x86_64

启动ElasticSerach

  1. 切换到用户elasticsearch:su elasticsearch;
  2. 进入目录/usr/local/work/elasticsearch-6.2.3;
  3. 执行启动命令:bin/elasticsearch -d,此时会在后台启动elasticsearch;
  4. 查看启动日志可执行命令:tail -f /usr/local/work/elasticsearch-6.2.3/logs/elasticsearch.log,大约五到十分钟后启动成功,提示如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[2018-04-07T10:12:27,392][INFO ][o.e.n.Node               ] initialized
[2018-04-07T10:12:27,392][INFO ][o.e.n.Node               ] [MNb1nGq] starting ...
[2018-04-07T10:12:39,676][INFO ][o.e.t.TransportService   ] [MNb1nGq] publish_address {127.0.0.1:9300}, bound_addresses {[::1]:9300}, {127.0.0.1:9300}
[2018-04-07T10:12:42,772][INFO ][o.e.c.s.MasterService    ] [MNb1nGq] zen-disco-elected-as-master ([0] nodes joined), reason: new_master {MNb1nGq}{MNb1nGq6Tn6VskdKFQckow}{_DglQhgmRsGAF2D7eTfVfg}{127.0.0.1}{127.0.0.1:9300}
[2018-04-07T10:12:42,776][INFO ][o.e.c.s.ClusterApplierService] [MNb1nGq] new_master {MNb1nGq}{MNb1nGq6Tn6VskdKFQckow}{_DglQhgmRsGAF2D7eTfVfg}{127.0.0.1}{127.0.0.1:9300}, reason: apply cluster state (from master [master {MNb1nGq}{MNb1nGq6Tn6VskdKFQckow}{_DglQhgmRsGAF2D7eTfVfg}{127.0.0.1}{127.0.0.1:9300} committed version [1] source [zen-disco-elected-as-master ([0] nodes joined)]])
[2018-04-07T10:12:42,817][INFO ][o.e.g.GatewayService     ] [MNb1nGq] recovered [0] indices into cluster_state
[2018-04-07T10:12:42,821][INFO ][o.e.h.n.Netty4HttpServerTransport] [MNb1nGq] publish_address {127.0.0.1:9200}, bound_addresses {[::1]:9200}, {127.0.0.1:9200}
[2018-04-07T10:12:42,821][INFO ][o.e.n.Node               ] [MNb1nGq] starte
  1. 执行curl命令检查服务是否正常响应:curl 127.0.0.1:9200,收到响应如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[elasticsearch@elk-server work]$ curl 127.0.0.1:9200
{
  "name" : "MNb1nGq",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "ZHkI7PCQTnCqMBM6rhyT5g",
  "version" : {
    "number" : "6.2.3",
    "build_hash" : "c59ff00",
    "build_date" : "2018-03-13T10:06:29.741383Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

至此,ElasticSerach服务启动成功,接下来是Logstash;

配置和启动Logstash

  1. 在目录/usr/local/work/logstash-6.2.3下创建文件default.conf,内容如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 监听5044端口作为输入
input {
	beats {
		port => "5044"
    }
}
# 数据过滤
filter {
    grok {
	    match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
    geoip {
		source => "clientip"
    }
}
# 输出配置为本机的9200端口,这是ElasticSerach服务的监听端口
output {
    elasticsearch {
	    hosts => ["127.0.0.1:9200"]
    }
}
  1. 后台启动Logstash服务:nohup bin/logstash -f default.conf --config.reload.automatic &
  2. 查看启动日志:tail -f logs/logstash-plain.log,启动成功的信息如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[2018-04-07T10:56:28,143][INFO ][logstash.runner          ] Starting Logstash {"logstash.version"=>"6.2.3"}
[2018-04-07T10:56:28,870][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}
[2018-04-07T10:56:33,639][INFO ][logstash.pipeline        ] Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>1, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50}
[2018-04-07T10:56:34,628][INFO ][logstash.outputs.elasticsearch] Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://127.0.0.1:9200/]}}
[2018-04-07T10:56:34,650][INFO ][logstash.outputs.elasticsearch] Running health check to see if an Elasticsearch connection is working {:healthcheck_url=>http://127.0.0.1:9200/, :path=>"/"}
[2018-04-07T10:56:35,147][WARN ][logstash.outputs.elasticsearch] Restored connection to ES instance {:url=>"http://127.0.0.1:9200/"}
[2018-04-07T10:56:35,245][INFO ][logstash.outputs.elasticsearch] ES Output version determined {:es_version=>6}
[2018-04-07T10:56:35,248][WARN ][logstash.outputs.elasticsearch] Detected a 6.x and above cluster: the `type` event field won't be used to determine the document _type {:es_version=>6}
[2018-04-07T10:56:35,304][INFO ][logstash.outputs.elasticsearch] Using mapping template from {:path=>nil}
[2018-04-07T10:56:35,333][INFO ][logstash.outputs.elasticsearch] Attempting to install template {:manage_template=>{"template"=>"logstash-*", "version"=>60001, "settings"=>{"index.refresh_interval"=>"5s"}, "mappings"=>{"_default_"=>{"dynamic_templates"=>[{"message_field"=>{"path_match"=>"message", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false}}}, {"string_fields"=>{"match"=>"*", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false, "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}}}}], "properties"=>{"@timestamp"=>{"type"=>"date"}, "@version"=>{"type"=>"keyword"}, "geoip"=>{"dynamic"=>true, "properties"=>{"ip"=>{"type"=>"ip"}, "location"=>{"type"=>"geo_point"}, "latitude"=>{"type"=>"half_float"}, "longitude"=>{"type"=>"half_float"}}}}}}}}
[2018-04-07T10:56:35,415][INFO ][logstash.outputs.elasticsearch] New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["//127.0.0.1:9200"]}
[2018-04-07T10:56:35,786][INFO ][logstash.filters.geoip   ] Using geoip database {:path=>"/usr/local/work/logstash-6.2.3/vendor/bundle/jruby/2.3.0/gems/logstash-filter-geoip-5.0.3-java/vendor/GeoLite2-City.mmdb"}
[2018-04-07T10:56:36,727][INFO ][logstash.inputs.beats    ] Beats inputs: Starting input listener {:address=>"0.0.0.0:5044"}
[2018-04-07T10:56:36,902][INFO ][logstash.pipeline        ] Pipeline started succesfully {:pipeline_id=>"main", :thread=>"#<Thread:0x427aed17 run>"}
[2018-04-07T10:56:36,967][INFO ][org.logstash.beats.Server] Starting server on port: 5044
[2018-04-07T10:56:37,083][INFO ][logstash.agent           ] Pipelines running {:count=>1, :pipelines=>["main"]}

Kibana

  1. 打开Kibana的配置文件/usr/local/work/kibana-6.2.3-linux-x86_64/config/kibana.yml,找到下面这行:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#server.host: "localhost"

改成如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server.host: "192.168.119.132"

这样其他电脑就能用浏览器访问Kibana的服务了; 2. 进入Kibana的目录:/usr/local/work/kibana-6.2.3-linux-x86_64 3. 执行启动命令:nohup bin/kibana & 4. 查看启动日志:tail -f nohup.out 5. 以下信息表示启动成功:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{"type":"log","@timestamp":"2018-04-07T04:44:59Z","tags":["status","plugin:elasticsearch@6.2.3","info"],"pid":3206,"state":"yellow","message":"Status changed from uninitialized to yellow - Waiting for Elasticsearch","prevState":"uninitialized","prevMsg":"uninitialized"}
{"type":"log","@timestamp":"2018-04-07T04:44:59Z","tags":["status","plugin:console@6.2.3","info"],"pid":3206,"state":"green","message":"Status changed from uninitialized to green - Ready","prevState":"uninitialized","prevMsg":"uninitialized"}
{"type":"log","@timestamp":"2018-04-07T04:45:01Z","tags":["status","plugin:timelion@6.2.3","info"],"pid":3206,"state":"green","message":"Status changed from uninitialized to green - Ready","prevState":"uninitialized","prevMsg":"uninitialized"}
{"type":"log","@timestamp":"2018-04-07T04:45:01Z","tags":["status","plugin:metrics@6.2.3","info"],"pid":3206,"state":"green","message":"Status changed from uninitialized to green - Ready","prevState":"uninitialized","prevMsg":"uninitialized"}
{"type":"log","@timestamp":"2018-04-07T04:45:01Z","tags":["listening","info"],"pid":3206,"message":"Server running at http://localhost:5601"}
{"type":"log","@timestamp":"2018-04-07T04:45:01Z","tags":["status","plugin:elasticsearch@6.2.3","info"],"pid":3206,"state":"green","message":"Status changed from yellow to green - Ready","prevState":"yellow","prevMsg":"Waiting for Elasticsearch"}
  1. 在浏览器访问http://192.168.119.132:5601,看到如下页面:

至此,ELK服务启动成功,接下来我们将业务日志上报上来,需要操作另一台电脑:nginx-server;

防火墙

首先,请关闭nginx-server的防火墙:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
systemctl stop firewalld.service && systemctl disable firewalld.service

安装Nginx

在nginx-server上安装并启动nginx服务,可以参考《 CentOS7安装Nginx1.10.1》

FileBeat

  1. 在nginx-server电脑创建目录/usr/local/work
  2. 在/usr/local/work目录下执行以下命令,下载FileBeat安装包:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.3-linux-x86_64.tar.gz**重点内容**
  1. 解压:tar -zxvf filebeat-6.2.3-linux-x86_64.tar.gz
  2. 打开文件/usr/local/work/filebeat-6.2.3-linux-x86_64/filebeat.yml,找到如下图的位置:
  1. 首先,将上图绿框中的enabled: false改为enabled: true;
  2. 其次,将上图红框中的- /var/log/*.log改为- /usr/local/nginx/logs/*.log;
  3. 继续修改filebeat.yml文件,找到下图两个红框中的内容,在每行的左侧添加"#",将这两行内容注释掉:
  1. 继续修改filebeat.yml文件,找到下图中的内容:

首先,将上图红框中的"#“去掉; 其次,将上图绿框那一行的左侧”#"去掉; 最后,将上图绿框中的内容从[“localhost:9200”]改为[“192.168.119.132:9200”](连接ElasticSerach); 改好的内容如下图;

  1. 启动FileBeat:./filebeat -e -c filebeat.yml -d “publish”

至此,FileBeat也启动成功了,接下来验证服务;

创建Index Patterns

  1. 通过浏览器多访问几次nginx服务,这样能多制造一些访问日志,访问地址:http://192.168.119.133
  2. 访问Kibana:http://192.168.119.132:5601,点击左上角的Discover,如下图红框,可以看到访问日志已经被ELK搜集了:
  1. 如下图,输入logstash-*,点击"Next step":
  1. 如下图,选择Time Filter,再点击“Create index pattern”:
  1. 页面提示创建Index Patterns成功:
  1. 点击左上角的"Discover"按钮,即可看到最新的日志信息,如下图:

至此,我们已经可以在ELK上查到Nginx的访问日志了,接下来将Tomcat的日志也接进来;

安装和启动Tomcat

  1. 确保nginx-server电脑上已经安装了JDK8;
  2. 在/usr/local/work/目录下执行以下命令,下载Tomcat:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.85/bin/apache-tomcat-7.0.85.zip
  1. 解压缩:unzip apache-tomcat-7.0.85.zip
  2. 给脚本赋予可执行权限:chmod a+x /usr/local/work/apache-tomcat-7.0.85/bin/*.sh
  3. 启动:/usr/local/work/apache-tomcat-7.0.85/bin/startup.sh
  4. 浏览器访问:http://192.168.119.133:8080,看到启动成功,如下图:
  1. 访问Tomcat提供的example服务的子页面:http://192.168.119.133:8080/examples/servlets/servlet/RequestInfoExample,如下图:

至此,Tomcat已经启动成功,接下来将Tomcat的访问日志接入ELK;

Tomcat访问日志接入ELK

  1. 打开FileBeat的配置文件/usr/local/work/filebeat-6.2.3-linux-x86_64/filebeat.yml,在"filebeat.prospectors:"下面新增一个配置节点,内容如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- type: log
  enabled: true
  paths:
    - /usr/local/work/apache-tomcat-7.0.85/logs/localhost_access_log.*.txt

配置好的filebeat.yml有两个type节点了,如下图:

2. 停掉filebeat服务,再用./filebeat -e -c filebeat.yml -d "publish"命令启动filebeat服务; 3. 此时在Kibana页面已经可以搜索到Tomcat的访问日志,以“RequestInfoExample”作为关键词搜索也能搜到对应的访问日志:

至此,ELK-6.2.3版本的服务和日志上报的搭建已经完成,后续如果还有业务服务器要上报日志,只需按照上述步骤安装和配置FileBeat即可;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
J2SE1.5的新特点(之一)
J2SE1.5的新特点<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> <?xml:namesp
田春峰-JCJC错别字检测
2019/02/14
5430
Java面试集合(二)
4.简单说说String类和StringBuffer类之间的区别? 答:String类是不可变的类,字符串一旦被初始化就不可能改变;StringBuffer是可变的字符串类,可以修改字符串的值。
达达前端
2019/07/03
3980
五、集合基础【黑马JavaSE笔记】
注:以上方法时List集合特有的方法,Collection集合没有这些方法,但是ArrayLIst集合有这些方法,因为ArrayList继承自List集合。
啵啵鱼
2022/11/23
7580
五、集合基础【黑马JavaSE笔记】
第50节:Java当中的泛型
这就存在一个问题,如果集合存储元素时,而且存储对象有很多,而且对象类型不相同,就很容易导致隐患。
达达前端
2019/07/03
6960
第50节:Java当中的泛型
【小家java】java5新特性(简述十大新特性) 重要一跃
所谓类型擦除指的就是Java源码中的范型信息只允许停留在编译前期,而编译后的字节码文件中将不再保留任何的范型信息。也就是说,范型信息在编译时将会被全部删除,其中范型类型的类型参数则会被替换为Object类型,并在实际使用时强制转换为指定的目标数据类型。而C++中的模板则会在编译时将模板类型中的类型参数根据所传递的指定数据类型生成相对应的目标代码。
YourBatman
2019/09/03
5650
Java 基础 -- 泛型、集合、IO、反射
计划把 Java 基础的有些部分再次看一遍,巩固一下,下面以及以后就会分享自己再次学习的一点笔记!不是有关标题的所有知识点,只是自己觉得模糊的一些知识点。 1.  对于泛型类而言,你若没有指明其类型,默认为Object; 2.  在继承泛型类以及接口的时候可以指明泛型的类型,也可以不指明; 3.   泛型也数据库中的应用:       写一个 DAO 类对数据库中的数据进行增删改查其类型声明为 <T> 。每张表对应一个类,对应每一张表实现一个类继承该 DAO 类并指明 DAO 泛型为该数据表对应的类,再实现
bgZyy
2018/05/16
9540
String、StringBuffer、StringBuilder三者之间的区别
String是不可变类,所以任何对String的操作都将引发新的String对象的生成。但是StringBuffer是可变类,任何对StringBuffer所指代的字符串改变都不会产生新的对象。
Michel_Rolle
2023/07/30
2.7K0
07 - JavaSE之容器
Collection 接口的子接口分为:Set接口(包含 HashSet类) + List接口(包含LinkedList 类和 ArrayLis t类) Map接口:包含HashMap类
Daotin
2018/08/31
3560
07 - JavaSE之容器
奇奇怪怪的面试题
两个线程并发执行下列代码,其中直接使用线程安全类ConcurrentHashMap的put方法时不需要考虑多线程间互相覆盖的问题。
九转成圣
2024/04/10
930
设计模式之访问者模式(行为型)
访问者模式:表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。所以访问者模式是一种对象行为型模式。
SmileNicky
2019/03/20
5520
Java 集合框架(List、Set、Map、Iterator、Stack、Properties)
相关文献:https://www.runoob.com/java/java-collections.html
Michael阿明
2021/09/06
3010
SpringBoot + ITextPdf:高效生成 PDF 预览文件
其实公司之前的项目里是用到了帆软报表的,然而最近接了一个新项目,这个项目独立部署在甲方的独立环境中,组长的意思是不用再单独部署一套帆软报表,成本太大,用其他方式实现一下。虽然我不太理解成本大在哪儿,不过身为助理工程师,别管那么多,照着干就完事了。
程序员皮皮林
2024/10/08
9760
SpringBoot + ITextPdf:高效生成 PDF 预览文件
JAVA: List用法
1、List中可以添加任何对象,包括自己定义的新的类。 class Person{ ..... } 上面定义了一个Person类,下面看好如何使用List Person p1=new Person(); Person p2=new Person(); List list=new ArrayList(); list.add(p1); list.add(p2);//这里是将对象加入到list中 for(int i=0;i Person p=(Person)list.get(i);//注意,这里一定要强制类型转
战神伽罗
2019/07/22
3.7K0
Map的5种遍历方法
//循环遍历map的方法 public class MapF { public static void main(String[] args) { Map<String, Integer> tempMap = new HashMap<String, Integer>(); tempMap.put("a","12"); tempMap.put("b","34"); tempMap.put("c","56");
挨踢小子部落阁
2023/03/16
6500
Map的5种遍历方法
Java 集合demo学习
以下实例演示了使用 Java Util 类的 Arrays.asList(name) 方法将数组转换为集合:
默 语
2024/11/20
460
Springboot输出PDF文件
有个人(死需求)跑过来跟你说,这些都给我输出成报告,pdf格式的,所以就有了下面这个,做一下笔记,以后有用直接过来拿。在网上找了一下,发现大家都是在用itext。iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。
用户3467126
2019/09/27
3K2
Springboot输出PDF文件
Java基础教程--安卓入门教程(七)
接口的基本语法 接口的基本语法(一) 使用interface定义 接口当中的方法都是抽象方法; 接口当中的方法都是public权限 接口中全是抽象函数,不能生成对象 interface USB{  public void read();  public void write(); } class USBPhone implements USB{ //复写  public void read(){   System.out.println("USBPhone read");  }  public void write(){   System.out.println("USBPhone write");  } } class Test{  public static void main(String args[]){   USBPhone usbPhone = new USBPhone();   USB usb = usbPhone;   usb.read();   usb.write();  } }
达达前端
2022/04/29
7000
Java基础教程--安卓入门教程(七)
JDK源码阅读:ArrayList原理
查询快:由于数组在内存中是一块连续空间,因此可以根据地址+索引的方式快速获取对应位置上的元素。
鳄鱼儿
2024/05/21
1320
Java基础之集合
-集合结构只要发生改变,迭代器必须重新获取,如果还是用的之前的迭代器,就会出现异常java.util.ConcurrentModificationException
shaoshaossm
2022/12/27
5330
Java基础之集合
itext7知识点研究(PDF编辑)
static class MyEventListener implements IEventListener { private List<Rectangle> rectangles = new ArrayList<>(); @Override public void eventOccurred(IEventData data, EventType type) { if (type == EventType.RENDER_TEXT) { TextRenderInfo renderInfo = (TextRenderInfo) data; Vector startPoint = renderInfo.getDescentLine().getStartPoint(); Vector endPoint = renderInfo.getAscentLine().getEndPoint(); float x1 = Math.min(startPoint.get(0), endPoint.get(0)); float x2 = Math.max(startPoint.get(0), endPoint.get(0)); float y1 = Math.min(startPoint.get(1), endPoint.get(1)); float y2 = Math.max(startPoint.get(1), endPoint.get(1)); rectangles.add(new Rectangle(x1, y1, x2 - x1, y2 - y1)); } } @Override public Set<EventType> getSupportedEvents() { return new LinkedHashSet<>(Collections.singletonList(EventType.RENDER_TEXT)); } public List<Rectangle> getRectangles() { return rectangles; } public void clear() { rectangles.clear(); } } static class MyCharacterEventListener extends MyEventListener { @Override public void eventOccurred(IEventData data, EventType type) { if (type == EventType.RENDER_TEXT) { TextRenderInfo renderInfo = (TextRenderInfo) data; for (TextRenderInfo tri : renderInfo.getCharacterRenderInfos()) { super.eventOccurred(tri, type); } } } }
老梁
2019/09/10
2.8K0
itext7知识点研究(PDF编辑)
相关推荐
J2SE1.5的新特点(之一)
更多 >
LV.1
腾讯工程师
目录
  • 环境规划
  • 部署情况简介
  • 关于Nginx安装
  • 安装JDK
  • 创建用户
  • 系统设置
  • elk-server:安装文件准备
  • 启动ElasticSerach
  • 配置和启动Logstash
  • Kibana
  • 防火墙
  • 安装Nginx
  • FileBeat
  • 创建Index Patterns
  • 安装和启动Tomcat
  • Tomcat访问日志接入ELK
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档