深度优先

这个家伙好懒,除了文章什么都没留下

0%

转自:https://www.dotblogs.com.tw/wasichris/2015/11/14/153922

前言

一般而言系统资料多来自远端资料库及WebAPI等,若频繁地从资料源捞取资料,有可能造成资料提供者的负担,且系统亦需承担因频繁捞取资料所造成的等待时间成本;这时我们可以考虑使用快取(Cache)来增加资料读取效率,避免上述冲击发生。 简单来说,快取就是以资料时效性及记忆体空间来换取资料获得效能,所以可能会面临资料不同步(资料源与快取)的问题,因此决定何时要收回快取来向资料源重新捞取资料,是程式开发者需要考量的一个重要议题,以下介绍几种不同快取回收时机,可以依照自身需求选择适用之条件。

快取使用方式

从.NET 4.0 开始,我们可以载入System.Runtime.Caching组件来实现快取机制,透过MemoryCache.Default来取得预设记忆体快取实体,使用方式就类似操作Session资料,但可依照需求来自定快取回收时机。

1. 加入快取(Set, Add, AddOrGetExisting)

  • Set (快取已存在时,直接覆写)
  • Cache[key]=value (快取已存在时,直接覆写,但无法设定CacheItemPolicy)
  • Add (快取已存在时,不会覆写原有设定,会回传false结果告知新增失败)

2. 设定快取回收时机(CacheItemPolicy)

让系统可以在适当的时机点再次向资料源请求资料,作为新快取值供系统取用,可用逻辑如下。

  • 指定时间是否到期(Expiration)
    • AbsoluteExpiration (ex. 设定快取后10s 回收快取)
    • SlidingExpiration (ex. 10s 内没人取用就回收快取)
  • 监控资料源是否改变(ChangeMonitor)
    • HostFileChangeMonitor (实体档案异动时回收快取)
    • SqlChangeMonitor (DB档案异动时回收快取)
    • CustomizedChangeMonitor ( 可以继承实作ChangeMonitor 类别来建立独有的监控逻辑)

3. 接收快取异动通知(Callback)

  • UpdateCallback (回收快取-前)
  • RemovedCallback (回收快取-后)

应用层面

举个简单范例来比较各种快取回收机制。 需求是这样,笔者有许多资料会放置在TXT档案中,这些资料都是系统会经常使用到的资讯,但我们不希望频繁地去读取该档案,以避免频繁读取磁碟而造成效能的消耗,因此希望加入快取来达成我们的目标;由于此范例重点在比较各快取收回机制效果,因此就不着墨适用性的问题了。

首先定义DataSourceProvide 做为资料来源类别,其中FileContents 属性会从实体档案中取得资料,接着会将资料存放于快取中,由于笔者想要验证不同快取回收机制所产生的效果,因此提供三种快取机制供切换测试使用;由于资料来自于实体档案,因此除了可在时间上的操作快取回收时机外,还可以使用HostFileChangeMonitor做为资料异动监视器,如有异动随即回收快取。 测试程式代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class DataSourceProvider
{
// fields
private ObjectCache _cache = MemoryCache.Default;

// proterties
public CacheEntryRemovedCallback OnFileContentsCacheRemove;

public string PolicyType { get; set; }

public string FileContents
{
get
{
string cacheKey = "FileContents";
string fileContents = _cache[cacheKey] as string;
if (string.IsNullOrWhiteSpace(fileContents))
{
// load file
string filePath = @"D:Holidays.txt";
fileContents = File.ReadAllText(filePath, Encoding.Default);

// set policy (when to remove cache)
var policy = new CacheItemPolicy();
policy.RemovedCallback = OnFileContentsCacheRemove;

// dynamic change policy for testing
switch (PolicyType)
{
case "1":
// 距離設定快取時間超過2秒後,回收快取
policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(2);
break;
case "2":
// 3秒期限內未使用快取時,回收快取
policy.SlidingExpiration = TimeSpan.FromSeconds(3);
break;
default:
// 資料異動時,回收快取
policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string>() { filePath }));
break;
}

// set cache
_cache.Set(cacheKey, fileContents, policy);
}

return fileContents;
}
}
}

测试主程式如下,可选择不同快取回收机制(CacheItemPolicy)来比较各自成效。 其中设定快取被回收后Callback方法,让它直接印出cache removed 讯息告知用户,方便后续测试时于画面显示快取被回收的时机点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
static void Main(string[] args)
{
// data source provider
var dataSource = new DataSourceProvider();

// set cache removed callback
dataSource.OnFileContentsCacheRemove = (arguments) =>
{
// cache key: arguments.CacheItem.Key
// cache value: arguments.CacheItem.Value as string

Console.WriteLine("==============> cache removed ");
};

// choose cache policy
Console.WriteLine("[1] AbsoluteExpiration(2s) ");
Console.WriteLine("[2] SlidingExpiration(3s) ");
Console.WriteLine("[3] ChangeMonitors ");
Console.Write("Please choose cache policy: ");
dataSource.PolicyType = Console.ReadLine();

// show data for testing cache
while (true)
{
Console.WriteLine("[time] " + DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss.fff"));
Console.WriteLine("[cache value] " + dataSource.FileContents);

string cmd = Console.ReadLine();
if (cmd == "exit") { break; }
}
}

程式启动后,首先就是选择所需使用的CacheItemPolicy 机制

当选择AbsoluteExpiration作为CacheItemPolicy 时,表示设定快取2秒后会回收快取; 从以下测试发现当设定快取后,时间超过2秒确实会回收快取,且在下一次取资料时,再次读取实体档案来载入至快取。

若使用SlidingExpiration作为快取Policy时,表示快取超过3秒没被取用的情况下,快取会自动被收回,结果如下图所示;所以换句话说,如果此快取密集地不断被取用(3秒内至少一次),此快取将永不被回收。

最后,若使用ChangeMonitors 作为快取Policy时,则表示当实体档案资料来源只要一有异动,快取就随即被收回;因此在这个CacheItemPolicy 中,快取回收机制将与时间没有任何关系了。

结论

综观上述三种方式,可能会有人觉得当然是使用ChangeMonitors 作为CacheItemPolicy 最好,在资料源被异动时马上收回快取,让资料不会有不同步的情况发生,又兼具快取特性;但是试想一个情况,当资料来源每秒都在不断地变动时(也许是汇率),而我所需的资料其实不需要这么即时,因为每次取得的汇率资料是可以被保留使用10秒钟,因此在这情境中是否可以使用AbsoluteExpiration作为快取回收机制,让快取经过10秒后过期被收回才会比较合适呢? 其实笔者想表达的意思是,快取的使用不一定适用所有情境,需要搭配不同快取回收机制才能达到提升效能的效果,因此请不要一昧地加注快取机制于系统中,否则可能会造成反效果。

参考资讯

http://blog.miniasp.com/post/2010/05/01/ASPNET-4-Cache-API-and-ObjectCache.aspx

http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/06/23/kb-cache-add-vs-cache-insert.aspx

原文地址:https://blog.csdn.net/reachyu/article/details/106575961

环境介绍

Go版本:1.13.1
开发工具:IntelliJ IDEA 2019.2.3 x64
开发环境:windows10 64位
部署环境:centos7

代码工程目录结构

代码直接build image部署

上传代码到centos7

Dockerfile内容

1
2
3
4
5
6
7
8
9
10
11
12
13
## 引入最新的golang ,不设置版本即为最新版本
FROM golang
## 在docker的根目录下创建相应的使用目录
RUN mkdir -p /www/webapp
## 设置程序在容器内的工作路径
WORKDIR /www/webapp
COPY . /www/webapp
## 编译
#RUN go build .
## 暴露容器内部端口
EXPOSE 9090
## 启动docker需要执行的文件
CMD go run main.go

制作镜像

Dockerfile和main.go在同一个目录

1
docker build -t appmng1.0:V1.0 -f Dockerfile .

代码直接build image,镜像非常大,如下图

启动容器

1
docker run --name appmng -d -p 9090:9090 appmng1.0:V1.0

访问

http://ip:9090/html

查看日志

1
docker logs 94af72d5961d

代码打包再build image部署

打包可执行文件

windows打包linux可执行文件,在项目根目录依次执行

1
2
3
SET GOARCH=amd64
SET GOOS=linux
go build

项目根目录会生成linux可执行文件

Dockerfile内容

1
2
3
4
5
6
7
8
9
10
11
12
#使用了镜像大小体积只有5MB的alpine镜像
FROM alpine:latest
#在docker的根目录下创建相应的使用目录
RUN mkdir -p /go/app
#设置工作路径
WORKDIR /go/app
#把Dockerfile同级目录所有文件拷贝到上面设置的容器的工作目录中
COPY . .
#暴露容器内部端口
EXPOSE 9090
#入口
ENTRYPOINT ["/go/app/appmng"]

制作镜像

应用打包的linux可执行文件和Dockefile放在同一个目录
注意:用打包的linux可执行文件要执行chmod 777,否则容器无法执行

1
docker build -t appmng:V1.0 -f Dockerfile .

代码打包后再build image,镜像通常只有几十兆,比第一种方式小了很多,但是这种方式,静态资源无法打入包中。

启动容器

1
docker run --name appmng-d -p 9090:9090 appmng:V1.0

Golang代理设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 引入最新的golang ,不设置版本即为最新版本
FROM golang
## 在docker的根目录下创建相应的使用目录
RUN mkdir -p /www/webapp
## 设置程序在容器内的工作路径
WORKDIR /www/webapp
COPY . /www/webapp
## 编译
#RUN go build .
## 暴露容器内部端口

RUN export GO111MODULE=on && \
export GOPROXY=https://goproxy.cn && \
go mod download

RUN go build -o main main.go

EXPOSE 8090
## 启动docker需要执行的文件
CMD go run main.go

原文地址:https://www.cnblogs.com/minghon/p/11853157.html

ELK简介

ELK是Elasticsearch、Logstash和Kibana首字母的缩写。这三者均是开源软件,这三套开源工具组合起来形成了一套强大的集中式日志管理平台

Elasticsearch是一个分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点,基于Apache Lucene构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通过简单的配置,Elasticsearch就会帮你管理集群、分片、故障转移、主节点选举等,还提供集群状态的监控接口。

Logstash是一个用来搜集、解析、过滤日志的工具。支持几乎任何类型的日志,包括系统日志、业务日志和安全日志,支持file、syslog、tcp、stdin、redis和kafka等多种接收方式。支持elasticrsearch、email、exec、nagios、tcp、hdfs等多种方式输出

Kibana是一个开源的分析与可视化平台,用于搜索、分析和可视化存储在 Elasticsearch中的数据,然后以图表的方式展现出来,还允许用户自定义查询、过滤和汇总数据。

安装(这里以windows为例)

  1. 第一步:下载Elasticsearch 下载地址:https://www.elastic.co/cn/downloads/elasticsearch 选择你适合的平台版本,如下图所示:

  1. 下载Logstash 下载地址:https://www.elastic.co/cn/downloads/logstash ,选择你适合的平台,如下图所示:

  1. 下载Kibana,下载地址:https://www.elastic.co/cn/downloads/kibana ,选择你适合的平台,如下图所示:

将压缩包解压到文件,如图所示:

切换到elasticsearch-7.3.2/bin,点击elasticsearch.bat 即可完成安装,打开http://localhost:9200/如下图所示即安装完成

安装node.js和grunt,从地址:https://nodejs.org/en/download/ 下载相应系统的 msi,双击安装

打开命令提示符输入npm install -g grunt-cli,如下图所示则grunt安装完成

进入/elasticsearch-7.3.2/config,打开elasticsearch.yml,在文件末尾加上以下代码:

1
2
http.cors.enabled: true
http.cors.allow-origin: "*"

双击elasticsearch.bat重启es

下载Head,下载地址:https://github.com/mobz/elasticsearch-head ,下载后将elasticsearch-head-master 解压到elasticsearch-7.3.2文件夹下,如图所示:

修改elasticsearch-head-master文件夹下的Gruntfile.js,加上hostname:’*’

在/elasticsearch-7.3.2/elasticsearch-head-master文件夹下执行 npm install

安装完成后执行grunt server 或者npm run start 运行head插件,http://浏览器下访问http://localhost:9100/

logstash安装:解压后启动使用配置文件就可以了

Kibana安装:kibana-7.3.2/config 文件夹下修改kibana.yml,取消server.port ,server.host,server.name,elasticsearch.hosts, i18n.locale前面的#号,并将i18n.locale的值改为zh-CN ,运行bin文件夹下的kibana.bat,打开localhost:5601,如图所示则安装成功

.Net Core使用Nlog调用ELK写入日志

  1. NuGet安装依赖

  2. 配置nlog.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogToConsole="true">
<extensions>
<add assembly="NLog.Targets.ElasticSearch"/>
</extensions>

<targets async="true">
<!--https://github.com/reactive-markets/NLog.Targets.ElasticSearch/wiki-->
<target xsi:type="ElasticSearch"
name="ElasticSearch"
uri="http://127.0.0.1:9200"
index="Web"
documentType="logevent"
includeAllProperties="false"
requireAuth="false">
<field name="host" layout="${machinename}" />
<field name="application"
layout="${applicationName}" />
<field name="logged" layout="${date}" />
<field name="level" layout="${level}" />
<field name="message" layout="${message}" />
<field name="logger" layout="${logger}" />
<field name="callSite" layout="${callsite:filename=true}" />
<field name="exception" layout="${exception:tostring}" />
<field name="IP" layout="${aspnet-request-ip}" />
<field name="User" layout="${aspnetcore-request-user}" />
<field name="serverName" layout="${machinename}" />
<field name="url" layout="${aspnetcore-request-url}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="INFO" writeTo="ElasticSearch" />
</rules>
</nlog>
  1. Startup.cs配置

  1. 应用

  1. 直接用控制台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using NLog;
using System;

namespace Demo.ELK.TestNLog
{
internal class Program
{
private static void Main(string[] args)
{
var _log = LogManager.GetCurrentClassLogger();
_log.Error("测试一下...........");
Console.WriteLine("Hello World!");
}
}
}

可以看到以下数据则表示调用成功

解决下载慢问题

  1. 安装Motrix,地址:

    https://motrix.app/zh-CN/

  2. 打开如下网址(Elasticsearch所有版本下载地址)

    https://www.elastic.co/cn/downloads/past-releases#elasticsearch

  3. 选择一个版本,例如我要下载7.7.1,然后按F12在网页源码中找到对应的下载地址

    https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.7.1-windows-x86_64.zip

  4. 然后将下载地址粘到用Motrix下载,具体操作如下图