首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >GEE APP——使用Sentinel-5p数据制作空气质量(气溶胶、甲烷、臭氧和二氧化氮)监测应用程序(北京市为例)

GEE APP——使用Sentinel-5p数据制作空气质量(气溶胶、甲烷、臭氧和二氧化氮)监测应用程序(北京市为例)

作者头像
此星光明
发布于 2024-05-16 07:17:03
发布于 2024-05-16 07:17:03
63400
代码可运行
举报
运行总次数:0
代码可运行

简介

空气质量是环境健康的一个重要方面,直接影响生态系统和人类的福祉。随着空气污染的后果日益明显,监测和了解大气参数的动态已成为当务之急。通过该项目,我们旨在利用卫星数据的能力,尤其是 2017 年 10 月 13 日发射的哨兵-5P 号卫星的数据,深入了解二氧化氮(NO2)、臭氧(O3)、二氧化硫(SO2)、一氧化碳(CO)、甲醛(HCHO)、甲烷(CH4)等关键大气成分,以及云层覆盖率和气溶胶指数。

数据集

Sentinel-5P

哨兵-5 前兆任务仪器收集的数据有助于评估空气质量。TROPOMI 仪器是一个多光谱传感器,可记录对测量大气中臭氧、甲烷、甲醛、气溶胶、一氧化碳、氧化氮和二氧化硫浓度以及云层特征非常重要的波长的反射率,空间分辨率为 0.01 弧度。

https://developers.google.com/earth-engine/datasets/catalog/sentinel-5p

二氧化氮(NO2): 二氧化氮是一种重要的空气污染物,主要来源于燃烧过程、工业活动和汽车尾气排放。监测二氧化氮水平对于评估人为活动对空气质量和公众健康的影响至关重要。

臭氧 (O3): 虽然高层大气中的臭氧可以吸收有害的紫外线辐射,对保护地球上的生命至关重要,但地面臭氧可能会损害人类健康。该参数是空气质量的一个关键指标,受到污染物和阳光复杂相互作用的影响。

二氧化硫 (SO2): 二氧化硫是燃烧含硫化石燃料产生的气体。监测二氧化硫水平对于跟踪工业排放和火山活动至关重要,这两者都会对环境和健康产生重大影响。

一氧化碳 (CO): 一氧化碳是一种无色无味的气体,由含碳燃料不完全燃烧产生。汽车尾气和工业生产过程会导致一氧化碳含量升高。监测一氧化碳有助于评估空气质量和潜在污染源。

甲醛 (CH2O): 甲醛是一种分子式为 CH2O、结构为 H-CHO 的有机化合物。甲醛是一种无色气体,有刺激性气味,主要来源于燃烧过程、工业活动和自然界。它在地面臭氧的形成过程中起着至关重要的作用,并导致空气质量下降。接触甲醛会对健康产生不良影响,包括刺激呼吸道和眼睛。

甲烷(CH4): 甲烷是一种强效温室气体,主要由自然过程(湿地、白蚁)和人类活动(如牲畜消化、稻田和化石燃料开采和加工)产生。虽然甲烷不会直接危害人类健康,但由于其具有很高的全球升温潜能值,因此是气候变化的重要因素。跟踪甲烷含量对气候研究和减排战略至关重要。

云层覆盖: 云在地球的能量平衡中发挥着重要作用,并影响着太阳辐射的分布。云层覆盖是气候研究中的一个关键因素,因为它影响温度、降水和整体天气模式。在卫星观测中,云层会遮挡地球表面的视线,影响测量的准确性。在空气质量监测研究中,采用了先进的算法和数据融合技术来减轻云层的影响。

气溶胶指数: 气溶胶指数(AI)是测量大气中气溶胶浓度的指标。气溶胶包括颗粒和液滴,其存在有多种来源,如污染、沙尘暴和火山爆发。气溶胶会影响空气质量、气候和人类健康。气溶胶会散射或吸收阳光,影响云的形成,吸入后还会引起呼吸道问题。

本文试图展示一个创新而简单的解决方案--利用谷歌地球引擎 (GEE) 和 Sentinel-5P 的强大功能开发的空气质量监测应用程序,该应用程序主要针对印度尼西亚。

首先要说明的是,哨兵-5P 数据有两种类型,即离线 (OFFL) 和近实时 (NRTI),指的是数据对用户的可用性和交付速度。下面是对两者区别的解释:

离线 (OFFL): 离线数据是指无法立即获得或访问的信息。就哨兵-5P 而言,离线数据通常是指卫星收集并存储以供日后使用的历史数据或存档数据。我们可以将离线数据用于回顾性研究、长期趋势分析和深入研究。这类数据不适合需要实时或接近实时信息的应用。

近实时(NRTI): 近实时数据指的是卫星采集后不久就能提供的信息。它不是瞬时数据,但从数据采集到提供给用户之间的延迟时间极短。近实时数据对于需要及时信息的应用至关重要,例如监测动态环境变化、应对自然灾害或为业务目的提供当前状态更新。近实时数据通常用于空气质量监测、灾害响应和气候研究等应用,在这些应用中,最新信息至关重要。

APP制作和数据处理过程

因此,既然我们要创建一个简单的空气质量监测应用程序,我们将使用近实时(NRTI)应用程序。下面将逐步介绍如何制作。

准备好我们要使用的资产,在本文中我使用的是北京市带县区的的 shapefile文件。您可以通过此链接访问。然后,将其定义为 prov。这里我们可以跟觉自己的需求改为其它名字,也就是district and county区县,当然不改也可以,这里只需要上传我们的二级矢量文件即可。

在此之前,我将代码分为三个部分,分别是可视化(Visualization)部分,其中包含与可视化相关的内容,如符号、图例设置等;日期配置(Date Configuration)部分,其中包含与我们的主要部件(即我们将放置在右下角的日期滑块部件)相关的设置;最后一部分是主函数(Main Function)部分,它是这个简单应用程序中将使用的主要函数,其中包含我们将使用的数据集以及与我们创建的日期滑块部件的连接。 从可视化部分开始,代码如下。首先,从北京市范围中设置我们的区域,并将其定义为区域,设置地图中心,然后创建标题小部件为 "北京市每周平均空气质量监测"。

下一步是设置符号,如调色板颜色设置、图例部件的彩条设置以及图例样式本身。我使用 Gena 提供的调色板软件包来创建彩条图例的调色板。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var pal = require('users/gena/packages:palettes');
var Jet = pal.misc.jet[7]
var BrBG = pal.colorbrewer.BrBG[10].reverse()
var Ice = pal.cmocean.Ice[7]
var Inferno = pal.matplotlib.inferno[7]

此外,如果您想添加省名标签,可以添加此代码。我在这一部分还使用了 Gena 的软件包:文本,从 shapefile 的 "provinsi "列中 "调用 "省名。但需要注意的是,添加这个标签会使数据加载时间更长。

我们必须将之前设置的所有内容组合成一个图例,并将其显示在我们创建的应用程序屏幕的左下角。

第二部分,即日期配置部分。首先,我们必须将时间从当前日期中剥离,因此为了更好地获取数据,第一次加载的数据将是前一天的数据。从该页面可以看到,可以获取的最新数据来自 Sentinel-5P 甲烷,即 2019-02-08。因此,我们只需将开始日期设置为 2019-01-01(注意:我们无法访问这两个日期之间的甲烷数据),从而采取中间方式。由于我们将显示每周数据,因此不要忘记将日期滑块 widget 中的日期周期设置为 7。

在主函数部分,我们将创建名为 updateVisualization 的主函数。因此,当我们点击日期滑块 widget 中的某个日期时,我们将显示该日期的数据(周平均值),所以正如你所看到的,在 endDateTime 变量中,我们将其设置为周平均值,在获取数据时,不要忘记添加 .mean() 并将其剪辑为区域,以便将其集中在印度尼西亚地区。

接下来是我们创建的应用程序的显示效果。要更改要查看的数据,可以在 "图层 "部分进行切换;要更改日期,可以在屏幕右下角的日期部件中进行更改。

函数

ui.Label(value, style, targetUrl, imageUrl)

A text label.

Arguments:

value (String, optional):

The text to display. Defaults to an empty string.

style (Object, optional):

An object of allowed CSS styles with their values to be set for this widget. See style() documentation.

targetUrl (String, optional):

The url to link to. Defaults to an empty string.

imageUrl (String, optional):

Optional image url. If provided, the label will be rendered as an image and the value text will be shown on mouse hover. Only data: urls and icons loaded from gstatic.com are allowed.

Returns: ui.Label

ui.Panel.Layout.flow(direction, wrap)

Returns a layout that places its widgets in a flow, either horizontal or vertical.

By default, widgets take up their natural space within a flow layout panel. Set the "stretch" style property on an added widget to stretch it to fill available space in the relevant direction:

  • horizontal, vertical, both

When multiple widgets are stretched, the available space is split equally among them. Panels are widgets themselves and can be stretched by specifying a "stretch" style property.

Arguments:

direction (String, optional):

The direction of the flow. One of

'horizontal' or 'vertical'. Defaults to 'vertical'.

wrap (Boolean, optional):

Whether to wrap children in the layout if there are too many to show in one line. Defaults to false.

Returns: ui.Panel.Layout

Map.getScale()

Returns the approximate pixel scale of the current map view, in meters.返回当前地图视图的大致像素比例尺(单位:米)。

No arguments.
Returns: Number|String

ui.Panel(widgets, layout, style)

A widget that can hold other widgets. Use panels to construct complex combinations of nested widgets.

Panels can be added to ui.root but not printed to the console with print().

可容纳其他部件的部件。使用面板可以构建嵌套 widget 的复杂组合。

面板可以添加到 ui.root 中,但不能使用 print() 打印到控制台。

Arguments:

widgets (List<ui.Widget>|ui.Widget, optional):

The list of widgets or a single widget to add to the panel. Defaults to an empty array.

layout (String|ui.Panel.Layout, optional):

The layout to use for this panel. If a string is passed in, it's taken as a shortcut to the layout constructor with that name. Defaults to 'flow'.

style (Object, optional):

An object of allowed CSS styles with their values to be set for this widget. See style() documentation.

Returns: ui.Panel

split(regex, flags)

Splits a string on a regular expression, Returning a list of strings.

Arguments:

this:string (String):

The string to split.

regex (String):

A regular expression to split on. If regex is the empty string, then the input string is split into individual characters.

flags (String, default: ""):

A string specifying the regular expression flag: 'i' (ignore case)

Returns: List

advance(delta, unit, timeZone)

Create a new Date by adding the specified units to the given Date.

Arguments:

this:date (Date)

delta (Float)

unit (String):

One of 'year', 'month' 'week', 'day', 'hour', 'minute', or 'second'.

timeZone (String, default: null):

The time zone (e.g. 'America/Los_Angeles'); defaults to UTC.

Returns: Date

ui.DateSlider(start, end, value, period, onChange, disabled, style)

A draggable target that ranges linearly between two dates. The date slider can be configured to display dates of various interval sizes, including day, 8-day, and year. The value of the slider is displayed as a label alongside it.

在两个日期之间线性移动的可拖动目标。日期滑块可配置为显示不同间隔大小的日期,包括日、8 日和年。滑块的值会以标签的形式显示在旁边。

Arguments:

start (Date|Number|String, optional):

The start date, as a UTC timestamp, date string, or ee.Date. Defaults to one week ago.

end (Date|Number|String, optional):

The end date, as a UTC timestamp, date string, or ee.Date. Defaults to today.

value (Date|Number|String, optional):

The initial value. The value is an array consisting of the start and end date for the selected date range, but for convenience, it can be set by specifying the start date alone. Defaults to yesterday.

period (Number, optional):

The interval size for values on the slider in days. Defaults to one.

onChange (Function, optional):

A callback to fire when the slider's state changes. The callback is passed an ee.DateRange representing the slider's current value and the slider widget.

disabled (Boolean, optional):

Whether the slider is disabled. Defaults to false.

style (Object, optional):

An object of allowed CSS styles with their values to be set for this widget. Defaults to an empty object.

Returns: ui.DateSlider

Map.layers()

Returns the list of layers associated with the default map.返回与默认地图相关的图层列表。

No arguments.
Returns: ui.data.ActiveList<ui.Map.AbstractLayer>

ee.reset()

Reset the library to its base state. Useful for re-initializing to a different server.

No arguments.

style(color, pointSize, pointShape, width, fillColor, styleProperty, neighborhood, lineType)

Draw a vector collection for visualization using a simple style language.

Arguments:

this:collection (FeatureCollection):

The collection to draw.

color (String, default: "black"):

A default color (CSS 3.0 color value e.g. 'FF0000' or 'red') to use for drawing the features. Supports opacity (e.g.: 'FF000088' for 50% transparent red).

pointSize (Integer, default: 3):

The default size in pixels of the point markers.

pointShape (String, default: "circle"):

The default shape of the marker to draw at each point location. One of: circle, square, diamond, cross, plus, pentagram, hexagram, triangle, triangle_up, triangle_down, triangle_left, triangle_right, pentagon, hexagon, star5, star6. This argument also supports the following Matlab marker abbreviations: o, s, d, x, +, p, h, ^, v, <, >.

width (Float, default: 2):

The default line width for lines and outlines for polygons and point shapes.

fillColor (String, default: null):

The color for filling polygons and point shapes. Defaults to 'color' at 0.66 opacity.

styleProperty (String, default: null):

A per-feature property expected to contain a dictionary. Values in the dictionary override any default values for that feature.

neighborhood (Integer, default: 5):

If styleProperty is used and any feature has a pointSize or width larger than the defaults, tiling artifacts can occur. Specifies the maximum neighborhood (pointSize + width) needed for any feature.

lineType (String, default: "solid"):

The default line style for lines and outlines of polygons and point shapes. Defaults to 'solid'. One of: solid, dotted, dashed.

Returns: Image

代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//加载研究去
var region = 
    /* color: #d63000 */
    /* shown: false */
    /* displayProperties: [
      {
        "type": "rectangle"
      }
    ] */
    ee.Geometry.Polygon(
        [[[115.07616668803962, 41.27242300777961],
          [115.07616668803962, 39.345751077160806],
          [117.66894012553962, 39.345751077160806],
          [117.66894012553962, 41.27242300777961]]], null, false),

//设定研究去指定的矢量数据,需要二级级文件
    prov = ee.FeatureCollection("users/bqt2000204051/beijing");


// 确定地图中心点
Map.centerObject(region, 5)

// 在地图中心设定APP条形标签
Map.add(ui.Label('Weekly Average AQ Monitor of Indonesia', {fontWeight: 'bold', fontSize: '28px'}));


// 可视化设定
var pal = require('users/gena/packages:palettes');
var Jet = pal.misc.jet[7]
var BrBG = pal.colorbrewer.BrBG[10].reverse()
var Ice = pal.cmocean.Ice[7]
var Inferno = pal.matplotlib.inferno[7]

// 气溶胶指数
var aiVis = { 
  min: -1, 
  max: 2, 
  palette: Jet
};
// 密度(一氧化碳、臭氧)
var densVis = { 
  min: 0, 
  max: 0.15, 
  palette: Inferno
};
// 密度(甲醛、氮、硫)
var densVis2 = { 
  min: 0, 
  max: 0.0005, 
  palette: Inferno
};
// 摩尔分数(甲烷)
var molfractVis = {
  min: 1750, 
  max: 1900, 
  palette: BrBG
};
// 云分数
var fractVis = {
  min: 0, 
  max: 1, 
  palette: Ice
};
// 边界颜色设定
var boundVis = {fillColor: "#00000000", color: '#FFFFFF', width: 2};

// 彩条
// 彩条数量
var nStepsR = 15;

// 颜色条小部件
function ColorBar(palette) {
  return ui.Thumbnail({ 
    image: ee.Image.pixelLonLat().select(0),
    params: {
      bbox: [0, 0, nStepsR, 0.5],
      dimensions: '100x5',
      format: 'png',
      min: 0,
      max: nStepsR,
      palette: palette,
    },
    style: {stretch: 'horizontal', margin: '0px 8px'},
  });
}

// 图例样式
// 返回一个带标签的图例,其中有一个颜色条和代表最小值、中间值和最大值的三个标签。

function makeLegend(title, vis) {
  var colorBar = ColorBar(vis.palette);
  
  var minLabel = vis.min.toString();
  var maxLabel = vis.max.toString();
  var midLabel = ((vis.min + vis.max) / 2).toFixed(2).toString(); // Compute the middle value and format it
  
  var labels = ui.Panel(
    [
      ui.Label(minLabel, {margin: '4px 8px'}),
      ui.Label(midLabel, {margin: '4px 8px', textAlign: 'center', stretch: 'horizontal'}),
      ui.Label(maxLabel, {margin: '4px 8px'})
    ],
    ui.Panel.Layout.flow('horizontal')
  );
  
  return ui.Panel(
    [
      ui.Label(title, {fontWeight: 'bold'}),
      colorBar,
      labels
    ]
  );
}

// 图例标题和脚注的样式
var LEGEND_TITLE_STYLE = {
  fontSize: '20px',
  fontWeight: 'bold',
  stretch: 'horizontal',
  textAlign: 'left',
  margin: '4px',
};

var LEGEND_FOOTNOTE_STYLE = {
  fontSize: '12px',
  stretch: 'horizontal',
  textAlign: 'left',
  margin: '4px',
};

// 管理标签(可选)

var text = require('users/gena/packages:text')

var scale = Map.getScale() + 0.5

var labels = prov.map(function(feat){
  feat = ee.Feature(feat)
  var name = ee.String(feat.get("provinsi"))
  var centroid = feat.geometry().centroid()
  var t = text.draw(name, centroid, scale, {
    fontSize: 10,
    textColor: 'white',
    outlineWidth: 0.5,
    outlineColor: 'black'
  })
  return t
})
var labels_final = ee.ImageCollection(labels)

// 组装图例面板
var legendPanel = ui.Panel(
  [
    ui.Label('Legend', LEGEND_TITLE_STYLE),
    makeLegend('Aerosol Index', aiVis),
    makeLegend('Compund Density - CO, O3 (mol/m^2)', densVis),
    makeLegend('Compund Density - CH2O, SO2, NO2  (mol/m^2)', densVis2),
    makeLegend('Compound Consentration - CH4 (mole fraction)', molfractVis),
    makeLegend('Cloud Coverage (fraction)', fractVis),
    ui.Label('Source: Sentinel-5P (ESA Copernicus)', LEGEND_FOOTNOTE_STYLE),
  ],
  ui.Panel.Layout.flow('vertical'),
  {width: '300px', position: 'bottom-left'}
);

// 添加面板到地图界面中
Map.add(legendPanel);

/*
 * 日期配置
 */
 
// 从当前日期中剥离时间
// 首次加载的数据是前一天的数据
var firstload = ee.Date(new Date().toISOString().split('T')[0]).advance(-1, 'day');
print(firstload);

// 可通过滑块访问的首个日期
var start_period = ee.Date('2019-01-01'); 

// 获取开始和结束日期
var startDate = start_period.getInfo();
var endDate = firstload.getInfo();

// 确定初始日期
var initialDate = firstload;

// 滑块功能
var dateSlider = ui.DateSlider({
  start: startDate.value, 
  end: endDate.value, 
  value: initialDate,
  period: 7, // 7-day granularity.
  style: {width: '300px', padding: '10px', position: 'bottom-right'},
  onChange: updateVisualization // Function to call when date changes.
});

// 创建一个面板,用于放置日期滑块和小时下拉菜单。
var dateTimePanel = ui.Panel({
  widgets: [dateSlider],
  layout: ui.Panel.Layout.flow('horizontal'), // Align widgets horizontally
  style: {position: 'bottom-right'}
});

Map.add(dateTimePanel);

/*
 * 主要功能和函数
 */
 
// 根据所选日期和时间更新可视化效果的函数。
function updateVisualization() {
  // 删除之前的图层
  Map.layers().reset();
  
  // 初始化日期
  var selectedDate = dateSlider.getValue();
  
  var selectedDateString = selectedDate.toString();
  var startDateString = selectedDateString.split(',')[0];
  var startDateTime = ee.Date(Number(startDateString));

  //  将所选日期转换为 ee.Date
  var date = startDateTime;
  
  // 结束日期(每周)
  var endDateTime = startDateTime.advance(1, 'week');
  
  // 管理边界
  var bound = prov.style(boundVis);

  // 根据该时间范围过滤您的采集并更新地图
  // 从哨兵-5P 一氧化碳中加载特定图像
  var CO = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_CO");
  var filteredCO = CO.filterDate(startDateTime, endDateTime);
  var specificCO = filteredCO.select('CO_column_number_density').mean().clip(region);

  // 从哨兵-5P 甲醛检测仪加载特定图像
  var HCHO = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_HCHO");
  var filteredHCHO = HCHO.filterDate(startDateTime, endDateTime);
  var specificHCHO = filteredHCHO.select('tropospheric_HCHO_column_number_density').mean().clip(region);
  
  // 从 "哨兵-5P 二氧化氮 "中加载特定图像
  var NO2 = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_NO2");
  var filteredNO2 = NO2.filterDate(startDateTime, endDateTime);
  var specificNO2 = filteredNO2.select('tropospheric_NO2_column_number_density').mean().clip(region);
  
  // 从哨兵-5P 臭氧中加载特定图像
  var O3 = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_O3");
  var filteredO3 = O3.filterDate(startDateTime, endDateTime);
  var specificO3 = filteredO3.select('O3_column_number_density').mean().clip(region);
  
  // 从哨兵-5P 二氧化硫卫星加载特定图像
  var SO2 = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_SO2");
  var filteredSO2 = SO2.filterDate(startDateTime, endDateTime);
  var specificSO2 = filteredSO2.select('SO2_column_number_density').mean().clip(region);
  
  // 从哨兵-5P 紫外线气溶胶指数中加载特定图像
  var AI = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_AER_AI");
  var filteredAI = AI.filterDate(startDateTime, endDateTime);
  var specificAI = filteredAI.select('absorbing_aerosol_index').mean().clip(region);
  
  // 从哨兵-5P 甲烷中加载特定图像
  var CH4 = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_CH4");
  var filteredCH4 = CH4.filterDate(startDateTime, endDateTime);
  var specificCH4 = filteredCH4.select('CH4_column_volume_mixing_ratio_dry_air').mean().clip(region);
  
  // 从哨兵-5P 云加载特定图像 
  var CL = ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_CLOUD");
  var filteredCL = CL.filterDate(startDateTime, endDateTime);
  var specificCL = filteredCL.select('cloud_fraction').mean().clip(region);

  // 显示数据
  Map.addLayer(specificCL, fractVis, 'Cloud Coverage', false);
  Map.addLayer(specificCH4, molfractVis, 'Methane (CH4)', false);
  Map.addLayer(specificSO2, densVis2, 'Sulfur Dioxide (SO2)', false);
  Map.addLayer(specificNO2, densVis2, 'Nitrogen Dioxide (NO2)', false);
  Map.addLayer(specificHCHO, densVis2, 'Formaldehyde (CH2O)', false);
  Map.addLayer(specificO3, densVis, 'Ozone (O3)', false);
  Map.addLayer(specificCO, densVis, 'Carbon Monoxide (CO)', false)
  Map.addLayer(specificAI, aiVis, 'Aerosol Index');
  
 // 添加管理边界
  Map.addLayer(bound, {}, 'Province', true, 0.7);
  Map.addLayer(labels_final, {}, 'Label', false)
}

// 初始可视化
updateVisualization();

结果

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
BTrace实现原理
BTrace是基于动态字节码修改技术(Hotswap)来实现运行时java程序的跟踪和替换。大体的原理可以用下面的公式描述:
十毛
2019/03/27
1.2K0
BTrace实现原理
JVMTM Tool Interface:JVM源码分析之javaagent原理完全解读
本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲到JVMTIAgent(C实现的),因为javaagent的运行还是依赖于一个特殊的JVMTIAgent。
一个会写诗的程序员
2020/05/18
1.8K0
JVMTM Tool Interface:JVM源码分析之javaagent原理完全解读
Java 调试工具、热部署、JVM 监控工具都用到了它
我们平时写 Java Agent 的机会确实不多,也可以说几乎用不着。但其实我们一直在用它,而且接触的机会非常多。下面这些技术都使用了 Java Agent 技术,看一下你就知道为什么了。
猿天地
2019/09/25
1K0
Java 调试工具、热部署、JVM 监控工具都用到了它
动态追踪技术之BTrace
BTrace 是一个开源项目。旨在为 java 提供安全可靠的动态跟踪分析工具。Btrace 基于动态字节码修改技术 (Hotswap) 来实现运行时 java 程序的跟踪和替换。Btrace的脚本是用纯java 编写的,基于一套官方提供的 annotation,使跟踪逻辑实现起来异常简单。
索码理
2022/12/28
8340
动态追踪技术之BTrace
Java 动态字节码技术
初学 Java 时,我对 IDEA 的 Debug 非常好奇,不止是它能查看断点的上下文环境,更神奇的是我可以在断点处使用它的 Evaluate 功能直接执行某些命令,进行一些计算或改变当前变量。
枕边书
2019/01/03
2.1K0
深入理解Instrument(一)
很早之前就了解到目前主流的APM开源框架如Pinpoint、SkyWalking等等都是通过java.lang.instrument包提供的字节码增强功能来实现的。趁着对这块的热情还没消退,抽时间分析一下java.lang.instrument包的使用方式,记录下来写成一个系列的文章。本系列博文针对的是JDK11,其他版本的JDK可能不适合。
Throwable
2020/06/23
3.1K0
深入理解Instrument(一)
冷门instrument包,功能d炸天
5版本以后,jdk有一个包叫做instrument,能够实现一些非常酷的功能。市面上一些APM工具,就是通过它来进行的增强。
xjjdog
2019/07/10
8440
冷门instrument包,功能d炸天
使用BTrace性能跟踪
BTrace是一个开源项目,开始于2007年,名声鹊起得益于2008年的JavaOne会议。
物流IT圈
2019/07/16
6150
使用BTrace性能跟踪
Java Agent(一)、初步认识Instrumentation
Instrumentation 是 Java SE 5 引入的一套 API,它允许开发者在运行时修改类的字节码。Java Instrumentation 可以实现在方法插入额外的字节码从而达到收集使用中的数据到指定工具的目的。Java.lang.instrument包的最大功能就是可以在已有的类上附加(修改)字节码来实现增强的逻辑,它最常见的用途包括:
有一只柴犬
2024/12/10
4030
Java Agent(一)、初步认识Instrumentation
Java系列 | 远程热部署在美团的落地实践
总第495篇 2022年 第012篇 Sonic是美团内部一款用于热部署的IDEA插件。本文主要讲述Sonic的实现细节以及底层原理,从IDEA插件到自动化部署,再到沉浸式开发产品闭环,全方位讲述了Sonic在美团的落地与实践经验。目前业界对标的产品并不多,希望本文能对从事联调/开发/测试等相关方向的同学有所帮助或启发。 1 前言 1.1 什么是热部署 1.2 为什么我们需要热部署 1.3 热部署难在哪 1.4 Sonic可以做什么 1.5 技术产品落地和推广实践经验 2 整体设计方案 2.1 Sonic
美团技术团队
2022/03/18
2.2K0
初到武汉,向你敬礼-salute|顺便解决个SkyWalking问题
上周六我正津津有味的看着「拆弹专家2」,刘德华扮演的“潘乘风”从片头的正义,凌然,到失去一条腿之后的厌世,愤恨,到后来的失忆,直到最后的自我救赎,真的很刺激啊,可是这个时候电话响了「出差武汉」,好吧,看完剩下的影片,吃个饭,回家开始订酒店,订机票,收拾行李,第二天出发武汉
狼王编程
2021/06/01
1K0
字节码调试的入口 —— JVM 的寄生插件 javaagent 那些事
Java Instrumentation 这个技术看起来非常神秘,很少有书会详细介绍。但是有很多工具是基于 Instrumentation 来实现的:
架构狂人
2023/08/16
1.1K0
字节码调试的入口 —— JVM 的寄生插件 javaagent 那些事
Java高级用法,写个代理侵入你 ?
大家好,我是小菜。一个希望能够成为 吹着牛X谈架构 的男人!如果你也想成为我想成为的人,不然点个关注做个伴,让小菜不再孤单!
蔡不菜丶
2022/09/21
4990
Java高级用法,写个代理侵入你 ?
谈谈Java Intrumentation和相关应用
  对于Java 程序员来说,Java Intrumentation、Java agent这些技术可能平时接触的很少,听上去陌生但又好像在哪里见到过。实际上,我们日常应用的各种工具中,有很多都是基于他们实现的,例如常见的热部署(JRebel, spring-loaded)、各种线上诊断工具(btrace, Greys)、代码覆盖率工具(JaCoCo)等等。   本文会介绍 Java Instrumentation及其相关概念,会涉及到的名词包括:
JavaEdge
2020/05/27
1.2K0
谈谈Java Intrumentation和相关应用
btrace-(字节码)动态跟踪工具
源码下载:https://gitee.com/hong99/spring.git (springboot_btrace)
逍遥壮士
2022/12/01
6230
btrace-(字节码)动态跟踪工具
动态追踪之java agent
上篇文章我们说到阿里的诊断工具Arthas对方法和类的监控使用的是动态追踪技术,本文我们将介绍动态追踪技术Java Agent。
索码理
2022/12/28
9690
动态追踪之java agent
认识 JavaAgent --获取目标进程已加载的所有类
之前在一个应用中搜索到一个类,但是在反序列化测试时出错,错误不是class notfound,是其他0xxx这样的错误,通过搜索,这个错误大概是类没有被加载。最近刚好看到了JavaAgent,初步学习了下,能进行拦截,主要通过Instrument Agent来进行字节码增强,可以进行字节码插桩,bTrace,Arthas 等操作,结合ASM,javassist,cglib框架能实现更强大的功能。Java RASP也是基于JavaAgent实现的。趁热记录下JavaAgent基础概念,以及简单使用JavaAgent实现一个获取目标进程已加载的类的测试。
Seebug漏洞平台
2019/12/16
2.3K0
认识 JavaAgent --获取目标进程已加载的所有类
JSP热部署的实现原理[通俗易懂]
对于Java应用程序来说,热部署就是在运行时更新Java类文件。在基于Java的应用服务器实现热部署的过程中,类装入器扮演着重要的角色。大多数基于Java的应用服务器,包括EJB服务器和Servlet容器,都支持热部署。类装入器不能重新装入一个已经装入的类,但只要使用一个新的类装入器实例,就可以将类再次装入一个正在运行的应用程序。
全栈程序员站长
2022/08/31
1.2K0
Java基础知识:探针技术
启动前探针使用方式比较局限,而且每次探针更改的时候,都需要重新启动应用,而主程序之后的探针程序就可以直接连接到已经启动的 jvm 中。可以实现例如动态替换类,查看加载类信息的一些功能。
DioxideCN
2022/08/05
1.6K0
Java面试快问快答-Instrument机制
使开发者可以构建一个独立于应用程序的代理程序Agent,用来监控和协助运行在JVM上的程序,更重要的是能够替换和修改某些类的定义;
JavaEdge
2020/05/26
7990
相关推荐
BTrace实现原理
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档