<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>The road</title><link>https://kane.mx/</link><description>Recent content on The road</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sat, 06 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://kane.mx/index.xml" rel="self" type="application/rss+xml"/><item><title>Multi-Tenant Bedrock Agents Security with Cedar</title><link>https://kane.mx/posts/2026/multi-tenant-agent-security-blueprint/</link><pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/multi-tenant-agent-security-blueprint/</guid><description>
&lt;h2 id="tldr-30-second-read">TL;DR (30-Second Read)&lt;/h2>
&lt;p>With Amazon Bedrock AgentCore now generally available — including &lt;strong>AgentCore Identity&lt;/strong> for agent authentication and &lt;strong>AgentCore Policy&lt;/strong>, which enforces Cedar rules by intercepting every tool call before execution — the security design for multi-tenant SaaS on Bedrock Agents has reached an inflection point. This blueprint addresses the hardest problem in agentic SaaS: a Large Language Model (LLM) that, through prompt injection or hallucination, crosses tenant boundaries or escalates privileges. The answer is a &lt;strong>zero-trust, low-latency, two-layer authorization architecture with real-time quota enforcement&lt;/strong>, built on Amazon Verified Permissions (AVP) and the Cedar policy engine.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/multi-tenant-agent-security-blueprint/">Read More&lt;/a>&lt;/p></description></item><item><title>S3 Vectors vs OpenSearch: Decision Tree from 30+ Projects</title><link>https://kane.mx/posts/2026/s3-vectors-vs-opensearch/</link><pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/s3-vectors-vs-opensearch/</guid><description>
&lt;p>Choosing a vector store on AWS for generative AI (GenAI) workloads used to be a one-line decision: pick Amazon OpenSearch Service or its serverless variant (AOSS) and move on. That changed when &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors.html">Amazon S3 Vectors&lt;/a> went GA in 2025. By storing vector data directly in S3 and pricing it on a fully consumption-based model, S3 Vectors has reset the cost-performance frontier for vector search.&lt;/p>
&lt;p>This post is not a rehash of the official documentation. It distills selection and tuning experience across more than 30 production GenAI projects shipped over the past year. You will get a decision tree, the cost-crossover math between the two services, and the specific migration pitfalls that bite hardest in practice — including the cosine-distance range mismatch and the metadata structure constraints.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/s3-vectors-vs-opensearch/">Read More&lt;/a>&lt;/p></description></item><item><title>MCP OAuth on AgentCore Gateway + Cognito via APIGW Façade</title><link>https://kane.mx/posts/2026/agentcore-gateway-cognito-mcp-oauth/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/agentcore-gateway-cognito-mcp-oauth/</guid><description>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>&lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html">Amazon Bedrock AgentCore Gateway&lt;/a> is the most pragmatic way to host a Model Context Protocol server on AWS today. Declare your tools as OpenAPI or as Lambda targets, get a managed multi-target MCP endpoint, and inherit AWS-native authentication via a &lt;code>customJwtAuthorizer&lt;/code>. For machine-to-machine traffic that pattern is excellent.&lt;/p>
&lt;p>The moment you ask an interactive MCP client — &lt;a href="https://docs.claude.com/en/docs/claude-code/overview">Claude Code&lt;/a>, Cursor, the &lt;a href="https://github.com/modelcontextprotocol/inspector">MCP Inspector&lt;/a> — to talk to that same gateway with a per-user OAuth flow, the seams show. AgentCore Gateway expects a JWT and trusts whatever issuer you wired into its authorizer. Pair it with &lt;a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html">Amazon Cognito&lt;/a> and the wiring works for the &lt;em>server&lt;/em> side. It does not work for the &lt;em>client&lt;/em> side, because Cognito is an OIDC identity provider, not an MCP-compliant authorization server. The two are not the same thing.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/agentcore-gateway-cognito-mcp-oauth/">Read More&lt;/a>&lt;/p></description></item><item><title>Claude Platform on AWS vs. Bedrock: A Decision Tree</title><link>https://kane.mx/posts/2026/claude-platform-on-aws-vs-bedrock/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/claude-platform-on-aws-vs-bedrock/</guid><description>
&lt;p>&amp;quot;Use Bedrock&amp;quot; was a one-line answer six months ago. As of May 11, 2026, it's not. Anthropic and AWS shipped &lt;a href="https://aws.amazon.com/blogs/machine-learning/introducing-claude-platform-on-aws-anthropics-native-platform-through-your-aws-account/">Claude Platform on AWS&lt;/a> to general availability — Anthropic's native developer platform, accessed through your AWS account, billed through AWS Marketplace, and operated by Anthropic outside the AWS security boundary.&lt;/p>
&lt;p>There are now three ways to run Claude when AWS is anywhere in the picture:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Amazon Bedrock&lt;/strong> — AWS operates inference; AWS is the data processor.&lt;/li>
&lt;li>&lt;strong>Claude Platform on AWS&lt;/strong> — Anthropic operates inference; Anthropic and AWS are independent data processors. Auth, billing, and audit go through AWS-native plumbing.&lt;/li>
&lt;li>&lt;strong>Claude Platform direct (claude.com)&lt;/strong> — Anthropic everything. AWS is not in the loop.&lt;/li>
&lt;/ol>
&lt;p>The choice has real architectural implications: feature availability, who holds your data, what your CloudTrail trail actually records, whether HIPAA workloads can run there, and whether your AWS EDP commit can absorb the spend. Pick wrong and you'll either re-platform when a beta you need only exists on one path, or re-architect when an auditor asks why model inference is leaving the AWS security boundary.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/claude-platform-on-aws-vs-bedrock/">Read More&lt;/a>&lt;/p></description></item><item><title>Agent Toolkit for AWS: What It Changes for Claude Code</title><link>https://kane.mx/posts/2026/agent-toolkit-for-aws-claude-code/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/agent-toolkit-for-aws-claude-code/</guid><description>
&lt;p>If you've been using Claude Code for AWS development, you've probably seen the pattern: you paste a CloudFormation snippet into your session, Claude suggests something plausible, you deploy it, and the stack events stream lights up with &lt;code>CREATE_FAILED&lt;/code> on a property the model couldn't have known about — because its training data stopped months ago.&lt;/p>
&lt;p>The usual workaround has been hand-rolling context into &lt;code>CLAUDE.md&lt;/code>: copying service endpoint quirks, IAM condition key syntax, and PrivateLink DNS formats that the model gets wrong. It works, but it's manual, fragile, and grows without bound.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/agent-toolkit-for-aws-claude-code/">Read More&lt;/a>&lt;/p></description></item><item><title>Self-Hosted GitHub Runners on AWS Spot for AI Dev Teams</title><link>https://kane.mx/posts/2026/self-hosted-github-runners-aws-spot/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/self-hosted-github-runners-aws-spot/</guid><description>
&lt;p>&lt;a href="https://kane.mx/posts/2026/autonomous-dev-team-openclaw/">Autonomous AI dev teams&lt;/a> move the bottleneck. When a dispatcher fans out work to dev and review agents every 5 minutes, the constraint is no longer human attention — it is the &lt;strong>CI/CD pipeline that gates every PR&lt;/strong>. Each agent push triggers builds, tests, E2E verification, and bot reviews. With even a small team of agents iterating in parallel, GitHub Actions minutes become the dominant operational cost.&lt;/p>
&lt;p>Hosted runners are convenient, but they are billed per-minute and capped at 2 cores on the standard tier. For a team of agents that pushes dozens of times an hour and runs container builds + Playwright suites, the math stops working. The lever is &lt;strong>self-hosted runners on AWS spot EC2&lt;/strong> — bigger instances, multi-architecture, scaling to zero when idle.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/self-hosted-github-runners-aws-spot/">Read More&lt;/a>&lt;/p></description></item><item><title>Track Claude Code Cost Per Project with Bedrock Tagging</title><link>https://kane.mx/posts/2026/claude-code-cost-per-project/</link><pubDate>Wed, 29 Apr 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/claude-code-cost-per-project/</guid><description>
&lt;p>If you run &lt;code>claude&lt;/code> against Amazon Bedrock across a dozen repos, your bill arrives as one opaque number. Until recently, the workaround was clunky — create an application inference profile per project, swap them by hand, hope you remembered which one was active. In April 2026, AWS &lt;a href="https://aws.amazon.com/blogs/machine-learning/introducing-granular-cost-attribution-for-amazon-bedrock/">shipped native per-principal cost attribution for Bedrock&lt;/a>: every &lt;code>InvokeModel&lt;/code> call now carries the caller's IAM principal and session tags straight into Cost Explorer and CUR 2.0. That is enough to turn a ~60-line shell recipe into a per-repo billing system.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/claude-code-cost-per-project/">Read More&lt;/a>&lt;/p></description></item><item><title>Transcribing Long Podcasts and Meetings with FunASR</title><link>https://kane.mx/posts/2026/funasr-podcast-transcription-openclaw/</link><pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/funasr-podcast-transcription-openclaw/</guid><description>
&lt;p>Two recordings sat on my disk waiting to be turned into searchable text. A 4-hour 13-minute discussion from a TGO founders' group — eight speakers, Chinese, Zoom audio. A 1-hour 8-minute podcast episode (屠龙之术 Vol.94 × 知本论) where two hosts spent the whole hour dissecting &lt;a href="https://www.xiaoyuzhoufm.com/episode/69e0d423b977fb2c471ea30c">OpenClaw&lt;/a> — its positioning, the AI-agent narrative, and investors' reactions.&lt;/p>
&lt;p>Both were full of specific claims, speaker-attributed opinions, and Chinese brand terms I wanted to grep later. Neither would transcribe cleanly with the tools I tried first.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/funasr-podcast-transcription-openclaw/">Read More&lt;/a>&lt;/p></description></item><item><title>From Solo AI Engineer to Autonomous Dev Team</title><link>https://kane.mx/posts/2026/autonomous-dev-team-openclaw/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/autonomous-dev-team-openclaw/</guid><description>
&lt;p>In a &lt;a href="https://kane.mx/posts/2026/ai-digital-engineer-claude-code/">previous post&lt;/a>, the &lt;strong>AI Digital Engineer&lt;/strong> pattern was introduced, featuring a single Claude Code agent guided by Skills and enforced by Hooks to execute a complete engineering workflow. This approach demonstrated effectiveness in delivering production-ready code with guaranteed quality gates.&lt;/p>
&lt;p>However, a fundamental limitation emerged: &lt;strong>one agent performing all tasks&lt;/strong>.&lt;/p>
&lt;p>This limitation highlighted the need for a multi-agent system, where a team of AI agents, each with a distinct role, could collaborate autonomously to transform GitHub issues into merged pull requests without human intervention.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/autonomous-dev-team-openclaw/">Read More&lt;/a>&lt;/p></description></item><item><title>Serverless Multi-Tenant OpenHands on AWS with Fargate</title><link>https://kane.mx/posts/2026/serverless-multi-tenant-openhands-on-aws/</link><pubDate>Mon, 02 Mar 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/serverless-multi-tenant-openhands-on-aws/</guid><description>
&lt;p>In a &lt;a href="https://kane.mx/posts/2026/deploying-openhands-on-aws-with-cdk/">previous post&lt;/a>, I introduced an &lt;a href="https://github.com/zxkane/openhands-infra">AWS CDK project&lt;/a> for deploying &lt;a href="https://github.com/All-Hands-AI/OpenHands">OpenHands&lt;/a> on EC2, featuring Cognito authentication and Aurora PostgreSQL. While this architecture successfully facilitated initial deployment, operating a shared AI coding platform for a team revealed three fundamental limitations:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Shared Resources&lt;/strong>: All sandbox containers executed on a single EC2 instance, leading to contention for CPU and memory.&lt;/li>
&lt;li>&lt;strong>Persistent Cost&lt;/strong>: The EC2 instance incurred approximately $375/month, regardless of platform utilization.&lt;/li>
&lt;li>&lt;strong>Lack of Tenant Isolation&lt;/strong>: Sandbox containers possessed network access to each other.&lt;/li>
&lt;/ol>
&lt;p>The &lt;a href="https://github.com/zxkane/openhands-infra/releases/tag/v1.0.0">v1.0.0 release&lt;/a> of &lt;code>openhands-infra&lt;/code> addresses these limitations by fully replacing EC2 with &lt;strong>ECS Fargate&lt;/strong>. This revised architecture provides per-conversation isolation through dedicated Fargate tasks, eliminates idle costs by stopping tasks when inactive, and prevents cross-tenant communication via granular security groups.&lt;/p>
&lt;p>This post details the architectural evolution and the AWS services that enable these capabilities.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/serverless-multi-tenant-openhands-on-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>AI Digital Engineer: End-to-End Delivery with Claude Code</title><link>https://kane.mx/posts/2026/ai-digital-engineer-claude-code/</link><pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/ai-digital-engineer-claude-code/</guid><description>
&lt;p>What if an AI could operate like a senior software engineer - not just writing code, but following the complete engineering process from design through deployment? This post introduces the &lt;strong>AI Digital Engineer&lt;/strong> pattern: a system that transforms Claude Code from an interactive assistant into an autonomous engineer capable of delivering production-ready software.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/ai-digital-engineer-claude-code/">Read More&lt;/a>&lt;/p></description></item><item><title>Deploying OpenHands AI Platform on AWS with CDK</title><link>https://kane.mx/posts/2026/deploying-openhands-on-aws-with-cdk/</link><pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/deploying-openhands-on-aws-with-cdk/</guid><description>
&lt;p>&lt;a href="https://github.com/All-Hands-AI/OpenHands">OpenHands&lt;/a> is an open-source AI-driven development platform that enables AI agents to write code, fix bugs, and execute complex development tasks autonomously. The default setup works well for local development, but what if you want to run it for a team or make it accessible from anywhere?&lt;/p>
&lt;p>This post introduces an &lt;a href="https://github.com/zxkane/openhands-infra">AWS CDK project&lt;/a> that extends OpenHands beyond single-user local usage. It adds multi-user authentication, persistent storage, and automatic recovery capabilities—transforming OpenHands into a shared service that your team can access from anywhere.&lt;/p>
&lt;h2 id="the-rise-of-cloud-based-ai-coding-agents">The Rise of Cloud-Based AI Coding Agents&lt;/h2>
&lt;p>The AI coding landscape has evolved rapidly. While IDE-integrated tools like GitHub Copilot focus on code completion, a new category of &lt;strong>autonomous AI coding agents&lt;/strong> has emerged—platforms that can independently plan, write, test, and deploy code with minimal human intervention.&lt;/p>
&lt;p>&lt;strong>Commercial cloud platforms&lt;/strong> now offer managed AI coding experiences:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://devin.ai/">Devin&lt;/a>&lt;/strong> (Cognition AI): The first widely-known autonomous AI software engineer, handling complete tasks from planning to deployment&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code&lt;/a>&lt;/strong>: Anthropic's agentic coding tool that runs in your terminal, with Claude.ai offering &lt;a href="https://support.anthropic.com/en/articles/9487310-what-are-artifacts-and-how-do-i-use-them">Artifacts&lt;/a> for interactive code generation&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://openai.com/codex">OpenAI Codex&lt;/a>&lt;/strong>: OpenAI's cloud-based coding agent running in sandboxed environments with GitHub integration&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://v0.dev/">v0&lt;/a>&lt;/strong> (Vercel): Cloud-based platform for generating full-stack applications with one-click deployment&lt;/li>
&lt;/ul>
&lt;p>These platforms provide convenience but come with trade-offs: &lt;strong>vendor lock-in&lt;/strong>, &lt;strong>data privacy concerns&lt;/strong>, &lt;strong>limited customization&lt;/strong>, and &lt;strong>recurring subscription costs&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Why self-host OpenHands?&lt;/strong>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Consideration&lt;/th>
&lt;th>Cloud Platforms&lt;/th>
&lt;th>Self-Hosted OpenHands&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Data privacy&lt;/td>
&lt;td>Data processed by third parties&lt;/td>
&lt;td>Your data stays in your AWS account&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Customization&lt;/td>
&lt;td>Limited to vendor features&lt;/td>
&lt;td>Full control over configuration&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Cost model&lt;/td>
&lt;td>Per-seat subscription&lt;/td>
&lt;td>Infrastructure cost (scales with usage)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>LLM choice&lt;/td>
&lt;td>Vendor-selected models&lt;/td>
&lt;td>Any model (Bedrock, OpenAI, local)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Integration&lt;/td>
&lt;td>Vendor-provided integrations&lt;/td>
&lt;td>Custom integrations via API&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>For organizations with strict compliance requirements, existing AWS infrastructure, or teams that prefer open-source solutions, self-hosting OpenHands provides the autonomous coding capabilities without the constraints of commercial platforms.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/deploying-openhands-on-aws-with-cdk/">Read More&lt;/a>&lt;/p></description></item><item><title>Secure AWS Credentials with credential_process</title><link>https://kane.mx/posts/2026/aws-credential-process/</link><pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2026/aws-credential-process/</guid><description>
&lt;p>Managing AWS credentials securely is a fundamental challenge for developers. Storing plain text access keys in &lt;code>~/.aws/credentials&lt;/code> creates significant security risks, especially when backing up dotfiles to version control systems. This post introduces &lt;code>credential_process&lt;/code>, a powerful AWS CLI feature that allows you to source credentials from external processes, enabling encrypted credential storage while maintaining seamless AWS access.&lt;/p>
&lt;h2 id="the-problem-with-plain-text-credentials">The Problem with Plain Text Credentials&lt;/h2>
&lt;p>The traditional approach stores AWS credentials in &lt;code>~/.aws/credentials&lt;/code>:&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2026/aws-credential-process/">Read More&lt;/a>&lt;/p></description></item><item><title>OIDC External Identity Source for AWS IAM Identity Center</title><link>https://kane.mx/posts/2025/external-identity-source-aws-sso/</link><pubDate>Wed, 31 Dec 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/external-identity-source-aws-sso/</guid><description>
&lt;p>AWS IAM Identity Center (formerly AWS SSO) provides centralized access management for AWS accounts and applications. While it natively supports SAML 2.0 for external identity providers, many organizations prefer OIDC-based authentication through providers like Amazon Cognito. This post demonstrates how to use &lt;a href="https://www.cloudflare.com/products/zero-trust/access/">Cloudflare Access&lt;/a> as a SAML bridge between Amazon Cognito and AWS IAM Identity Center with automatic just-in-time (JIT) user provisioning.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/external-identity-source-aws-sso/">Read More&lt;/a>&lt;/p></description></item><item><title>Desktop Notifications for Claude Code: Never Miss a Completed Task</title><link>https://kane.mx/posts/2025/claude-code-notification-hooks/</link><pubDate>Tue, 02 Dec 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/claude-code-notification-hooks/</guid><description>
&lt;p>When working with Claude Code on complex tasks, you often switch to other work while waiting for completion. The challenge? Knowing exactly when Claude finishes so you can review the results promptly. This post shows you how to configure desktop notifications that alert you the moment Claude Code completes a task.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/claude-code-notification-hooks/">Read More&lt;/a>&lt;/p></description></item><item><title>MCP OAuth Evolution: SEP-991 Simplifies Client Registration</title><link>https://kane.mx/posts/2025/mcp-oauth-sep-991-simplified-registration/</link><pubDate>Tue, 02 Dec 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/mcp-oauth-sep-991-simplified-registration/</guid><description>
&lt;h2 id="the-problem-with-dynamic-client-registration">The Problem with Dynamic Client Registration&lt;/h2>
&lt;p>In my &lt;a href="https://kane.mx/posts/2025/mcp-authorization-oauth-rfc-deep-dive/">previous deep-dive into MCP authorization&lt;/a>, I analyzed how the protocol builds on OAuth 2.1 with mandatory PKCE, Resource Indicators (RFC 8707), and the &amp;quot;Discovery Trifecta&amp;quot; of RFC 7591, 8414, and 9728. Dynamic Client Registration (DCR) was positioned as the key enabler for MCP's federated ecosystem.&lt;/p>
&lt;p>However, DCR has significant practical limitations:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Challenge&lt;/th>
&lt;th>Impact&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Requires AS support for public registration API&lt;/td>
&lt;td>Many identity providers don't offer this&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Forces OAuth proxy infrastructure&lt;/td>
&lt;td>Added complexity when AS lacks DCR&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Manual IT involvement&lt;/td>
&lt;td>End users need admin help for each registration&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The MCP ecosystem faces a unique challenge: &lt;strong>unbounded clients connecting to unbounded servers&lt;/strong> with no prior relationship. DCR, while standardized, often requires workarounds in practice.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/mcp-oauth-sep-991-simplified-registration/">Read More&lt;/a>&lt;/p></description></item><item><title>Implementing MCP OAuth 2.1 with Keycloak on AWS</title><link>https://kane.mx/posts/2025/deploy-keycloak-aws-mcp-oauth/</link><pubDate>Fri, 21 Nov 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/deploy-keycloak-aws-mcp-oauth/</guid><description>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>The Model Context Protocol (MCP) ecosystem mandates OAuth 2.1-compliant authorization servers to facilitate secure, federated access to AI model services. MCP clients, such as Claude Code, Cursor, and VS Code extensions, rely on modern OAuth specifications including Dynamic Client Registration (RFC 7591), PKCE (RFC 7636), and crucially, Resource Indicators (RFC 8707) for audience-restricted tokens.&lt;/p>
&lt;p>However, most Identity-as-a-Service (IDaaS) providers, including the open-source Keycloak platform, currently lack full RFC 8707 support. Keycloak, while robust in OAuth 2.0 capabilities, employs a proprietary &lt;code>audience&lt;/code> parameter in contrast to the standardized &lt;code>resource&lt;/code> parameter defined in RFC 8707. For a comprehensive analysis of this compatibility landscape, refer to my previous post: &lt;a href="https://kane.mx/posts/2025/mcp-authorization-oauth-rfc-deep-dive/">Technical Deconstruction of MCP Authorization: A Deep Dive into OAuth 2.1 and IETF RFC Specifications&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/deploy-keycloak-aws-mcp-oauth/">Read More&lt;/a>&lt;/p></description></item><item><title>Xiaozhi ESP32 MCP Gateway with Amazon Bedrock AgentCore</title><link>https://kane.mx/posts/2025/xiaozhi-agentcore-gateway-mcp/</link><pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/xiaozhi-agentcore-gateway-mcp/</guid><description>
&lt;p>The &lt;a href="https://github.com/78/xiaozhi-esp32">Xiaozhi hardware&lt;/a> is an impressive ESP32-based AI voice assistant capable of offline wake-up, multi-language support, and cloud connectivity. But what if you want your Xiaozhi device to access multiple AI tools, APIs, and services without managing complex integrations on the hardware side? This is where Amazon Bedrock AgentCore Gateway shines as a unified aggregation layer for Model Context Protocol (MCP) servers.&lt;/p>
&lt;p>In this guide, I'll walk you through building a distributed MCP architecture that connects Xiaozhi hardware to multiple cloud services through a single WebSocket connection, leveraging AgentCore Gateway to aggregate tools ranging from simple calculators to complex RESTful APIs like real-time football data.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/xiaozhi-agentcore-gateway-mcp/">Read More&lt;/a>&lt;/p></description></item><item><title>Beyond Prompts: 4 Context Engineering Secrets for Claude Code</title><link>https://kane.mx/posts/2025/context-engineering-secrets-claude-code/</link><pubDate>Fri, 14 Nov 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/context-engineering-secrets-claude-code/</guid><description>
&lt;p>You can stop hoping your Large Language Model (LLM) follows complex instructions. &lt;strong>Context Engineering&lt;/strong> is the strategic practice of curating what enters the model's limited attention budget. To build reliable AI agents, you must master these four deterministic context patterns.&lt;/p>
&lt;p>This post explores the key insights from my presentation &amp;quot;&lt;a href="https://docs.google.com/presentation/d/1fifANGCI85B4Pxz6XhLN0CeI3fTVS-ktsWfFBrhx2Do/edit?usp=sharing">Claude Code Skill(s): Mastering AI-Powered Development&lt;/a>&amp;quot;, focusing on practical patterns that transform unpredictable AI interactions into deterministic, production-ready workflows.&lt;/p>
&lt;h2 id="what-is-context-engineering">What is Context Engineering?&lt;/h2>
&lt;p>Context Engineering is the art and science of strategically managing what information an LLM processes within its limited attention window. Unlike traditional prompt engineering, which focuses on crafting individual requests, context engineering treats the entire development environment as a programmable context system.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/context-engineering-secrets-claude-code/">Read More&lt;/a>&lt;/p></description></item><item><title>Technical Deconstruction of MCP Authorization: A Deep Dive into OAuth 2.1 and IETF RFC Specifications</title><link>https://kane.mx/posts/2025/mcp-authorization-oauth-rfc-deep-dive/</link><pubDate>Wed, 12 Nov 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/mcp-authorization-oauth-rfc-deep-dive/</guid><description>
&lt;h2 id="executive-summary">Executive Summary&lt;/h2>
&lt;p>This article provides a deep-dive technical analysis of the Model Context Protocol (MCP) authorization flow. The central insight is that MCP's authorization model is not a generic application of OAuth 2.0 but a sophisticated implementation of the emerging &lt;strong>OAuth 2.1 standard&lt;/strong>.&lt;/p>
&lt;p>The MCP protocol deliberately rejects the flexible but less secure patterns of the original 2012 OAuth framework (RFC 6749). Instead, it adopts a modern, secure-by-default, and dynamic protocol stack built on three pillars:&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/mcp-authorization-oauth-rfc-deep-dive/">Read More&lt;/a>&lt;/p></description></item><item><title>How to Fix Shift+Enter in VS Code Remote SSH for Claude Code</title><link>https://kane.mx/posts/2025/vscode-remote-ssh-claude-code-keybindings/</link><pubDate>Thu, 06 Nov 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/vscode-remote-ssh-claude-code-keybindings/</guid><description>
&lt;h2 id="the-problem-premature-input-submission">The Problem: Premature Input Submission&lt;/h2>
&lt;p>When working with Claude Code in a VS Code Remote SSH session (e.g., connecting from a macOS or Windows client to a remote Linux host), a common frustration arises: pressing &lt;code>Shift+Enter&lt;/code> in the terminal is supposed to create a new line for multi-line input. Instead, it often submits the current line prematurely.&lt;/p>
&lt;p>This behavior disrupts the workflow for crafting complex, multi-line prompts, leading to fragmented interactions and inefficient token usage.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/vscode-remote-ssh-claude-code-keybindings/">Read More&lt;/a>&lt;/p></description></item><item><title>Amazon Quick Suite Deep Dive: Build AI-Powered Business Intelligence on AWS</title><link>https://kane.mx/posts/2025/amazon-quicksuite-deep-dive/</link><pubDate>Wed, 29 Oct 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/amazon-quicksuite-deep-dive/</guid><description>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>Business intelligence has long been the domain of specialists, requiring complex tools and time-consuming analysis. But what if you could simply &lt;em>ask&lt;/em> your data questions in plain English and receive comprehensive, visualized answers in seconds? What if you could automate your weekly reporting with a simple conversation?&lt;/p>
&lt;p>&lt;strong>Amazon Quick Suite&lt;/strong> is AWS's answer. It's a generative AI-powered business intelligence platform designed to democratize data analysis, making it accessible to everyone in your organization—no machine learning expertise required.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/amazon-quicksuite-deep-dive/">Read More&lt;/a>&lt;/p></description></item><item><title>Build on AWS Faster with Claude Code and AWS Skills</title><link>https://kane.mx/posts/2025/aws-skills-claude-code/</link><pubDate>Sun, 26 Oct 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/aws-skills-claude-code/</guid><description>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>Building on AWS is powerful but complex. What if your AI assistant had deep AWS expertise built-in? That's what &lt;strong>AWS Skills&lt;/strong> brings to Claude Code.&lt;/p>
&lt;p>&lt;a href="https://github.com/zxkane/aws-skills">AWS Skills&lt;/a> is a plugin that transforms Claude Code into an intelligent AWS development partner. It understands CDK best practices, estimates costs before you deploy, and guides you through serverless patterns. This post shows you how to build a serverless REST API using Claude Code supercharged with AWS Skills.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/aws-skills-claude-code/">Read More&lt;/a>&lt;/p></description></item><item><title>Upgrade to Claude Agent SDK: A Quick Migration Guide from Claude Code</title><link>https://kane.mx/posts/2025/claude-agent-sdk-update/</link><pubDate>Tue, 30 Sep 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/claude-agent-sdk-update/</guid><description>
&lt;p>Heads up, builders! You may have noticed that Anthropic has rebranded the &lt;strong>Claude Code SDK&lt;/strong> to the new &lt;strong>Claude Agent SDK&lt;/strong>.&lt;/p>
&lt;p>This is more than just a new name. As the &lt;a href="https://www.anthropic.com/engineering/building-agents-with-the-claude-agent-sdk">official announcement&lt;/a> explains, this change reflects a strategic focus on making it easier than ever to build, debug, and deploy powerful AI agents.&lt;/p>
&lt;p>If you've been following our &lt;a href="https://kane.mx/posts/2025/claude-code-agent-framework/">deep dive into building agentic applications&lt;/a>, you'll be happy to know that the migration is incredibly straightforward. All the core concepts and powerful features like conversation management, MCP integration, and response streaming are still there.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/claude-agent-sdk-update/">Read More&lt;/a>&lt;/p></description></item><item><title>Building Agentic Applications with Claude Code: A Developer's Guide to AI-Powered Automation</title><link>https://kane.mx/posts/2025/claude-code-agent-framework/</link><pubDate>Mon, 29 Sep 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/claude-code-agent-framework/</guid><description>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>If you've been following the AI space, you know that &amp;quot;agents&amp;quot; are the next big thing. These autonomous, intelligent systems promise to revolutionize how we automate complex tasks. But building them can be a daunting undertaking, often involving a tangled web of conversation management, tool integration, and state tracking.&lt;/p>
&lt;p>What if I told you there's a framework that handles the heavy lifting, letting you focus on your agent's unique logic? Enter &lt;strong>Claude Code&lt;/strong>. It has evolved beyond a simple CLI tool into a powerful AI application framework for building sophisticated AI applications.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/claude-code-agent-framework/">Read More&lt;/a>&lt;/p></description></item><item><title>Leveraging MCP Client's OAuthClientProvider for Seamless AWS AgentCore Authentication</title><link>https://kane.mx/posts/2025/use-mcp-client-oauthclientprovider-invoke-mcp-hosted-on-aws-agentcore/</link><pubDate>Thu, 04 Sep 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/use-mcp-client-oauthclientprovider-invoke-mcp-hosted-on-aws-agentcore/</guid><description>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Building on my &lt;a href="https://kane.mx/posts/2025/invoke-mcp-hosted-on-aws-agentcore/">previous exploration of connecting to MCP servers hosted on AWS AgentCore&lt;/a>, I've been working extensively with the native MCP SDK's OAuth Client Provider to streamline authentication workflows. The MCP SDK's built-in OAuth support has evolved significantly, offering robust solutions for both interactive user authentication and machine-to-machine (M2M) flows.&lt;/p>
&lt;p>In this follow-up article, I'll share the key improvements and special techniques I've discovered for using the MCP Client's &lt;code>OAuthClientProvider&lt;/code> with AWS AgentCore, including handling AgentCore's unique behavior with 403 responses, implementing M2M authentication flows, and leveraging automatic token refresh capabilities.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/use-mcp-client-oauthclientprovider-invoke-mcp-hosted-on-aws-agentcore/">Read More&lt;/a>&lt;/p></description></item><item><title>How invoking remote MCP servers hosted on AWS AgentCore</title><link>https://kane.mx/posts/2025/invoke-mcp-hosted-on-aws-agentcore/</link><pubDate>Fri, 22 Aug 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/invoke-mcp-hosted-on-aws-agentcore/</guid><description>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Recently, I've been exploring &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/">AWS AgentCore&lt;/a>'s new capability to host &lt;a href="https://modelcontextprotocol.io/">Model Context Protocol (MCP)&lt;/a> servers, and I wanted to share my experience with connecting to these remote servers as a client. The Model Context Protocol is an open standard that enables AI assistants to securely connect with external data sources and tools, and AWS AgentCore provides a managed hosting environment for these servers with built-in authentication and scaling capabilities.&lt;/p>
&lt;p>In this article, I'll walk through the process of invoking MCP servers hosted on &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-mcp.html">AWS AgentCore Runtime&lt;/a> or proxied via &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html">AgentCore Gateway&lt;/a>, covering different authentication methods, client implementation patterns, and practical considerations. What struck me most about this approach is how it bridges the gap between local development and enterprise-grade deployment while maintaining the flexibility that makes MCP so powerful.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/invoke-mcp-hosted-on-aws-agentcore/">Read More&lt;/a>&lt;/p></description></item><item><title>Build Agentic Chatbot on AWS with Amazon Bedrock</title><link>https://kane.mx/posts/2025/build-agentic-chatbot-on-aws/</link><pubDate>Mon, 07 Apr 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/build-agentic-chatbot-on-aws/</guid><description>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>In this article, I'll share my experience building an agentic chatbot on AWS using Amazon Bedrock, Amplify Gen2, and Amplify AI kit. This project, called Industry Assistant Portal, serves as an internal industry assistant that provides industry-specific AWS solutions guidance. The chatbot leverages Amazon Bedrock's powerful foundation models and knowledge base capabilities to deliver contextually relevant information about AWS industry solutions.&lt;/p>
&lt;p>The journey of building this chatbot taught me valuable lessons about implementing agentic AI systems that can reason, plan, and execute complex tasks while maintaining context awareness. I'll cover the architecture, implementation details, challenges faced, and key learnings from this project.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/build-agentic-chatbot-on-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>2025 AI Developer Tools Benchmark: Comprehensive IDE &amp; Assistant Comparison</title><link>https://kane.mx/posts/2025/ai-developer-tools-benchmark-comparison/</link><pubDate>Fri, 17 Jan 2025 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2025/ai-developer-tools-benchmark-comparison/</guid><description>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>This comprehensive benchmark evaluates the capabilities of 10 leading AI-powered developer tools and IDEs. The focus is on their ability to autonomously complete real-world programming tasks through natural language conversations, minimizing the need for manual coding. The evaluation excludes common features like code explanation, completion, unit testing, and documentation generation to focus on advanced AI capabilities.&lt;/p>
&lt;p>&lt;strong>Testing Period&lt;/strong>: Late December 2024 to Mid-January 2025&lt;br>
&lt;strong>Tools Tested&lt;/strong>: 10 major AI development assistants&lt;br>
&lt;strong>Tasks Evaluated&lt;/strong>: 3 real-world programming scenarios&lt;br>
&lt;strong>Note&lt;/strong>: Several tools were tested across multiple versions during this period.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2025/ai-developer-tools-benchmark-comparison/">Read More&lt;/a>&lt;/p></description></item><item><title>Create Amazing Images with Amazon Nova and Model Context Protocol</title><link>https://kane.mx/posts/2024/ai-image-generation-with-amazon-nova/</link><pubDate>Tue, 31 Dec 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/ai-image-generation-with-amazon-nova/</guid><description>
&lt;p>Ever wished you could conjure up the perfect images for your blog posts or articles without leaving your editor? Wouldn't it be amazing to generate professional-quality visuals with just a few keystrokes while you're in your creative flow?&lt;/p>
&lt;p>Well, grab your virtual paintbrush because we're about to dive into how you can do exactly that using GenAI's image generation capabilities with Model Context Protocol (MCP) server!&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/ai-image-generation-with-amazon-nova/">Read More&lt;/a>&lt;/p></description></item><item><title>Nine Essential Tips of AWS Amplify for Boosting Development Productivity</title><link>https://kane.mx/posts/2024/aws-amplify-you-need-to-know/</link><pubDate>Tue, 24 Dec 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/aws-amplify-you-need-to-know/</guid><description>
&lt;p>AWS Amplify is a powerful set of tools and services for developing, hosting, and managing serverless applications. With the recent launch of Amplify Gen 2&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>, the platform has evolved significantly to enhance the developer experience. In this guide, we'll explore nine essential tips that will help you maximize your productivity with AWS Amplify, covering everything from authentication and infrastructure management to AI integration and deployment.&lt;/p>
&lt;h2 id="understanding-amplify-gen-2">Understanding Amplify Gen 2&lt;/h2>
&lt;p>Before diving into the tips, let's understand what makes Amplify Gen 2 special. It introduces a code-first developer experience that enables building fullstack applications using TypeScript. Key benefits include:&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/aws-amplify-you-need-to-know/">Read More&lt;/a>&lt;/p></description></item><item><title>AI 真能编程了吗？</title><link>https://kane.mx/posts/2024/ai-copilot-for-programming/</link><pubDate>Wed, 13 Nov 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/ai-copilot-for-programming/</guid><description>
&lt;p>如果你平时关注科技圈的动态，那么你一定在朋友圈或直播中看到过这样的&lt;a href="https://weixin.sogou.com/weixin?type=2&amp;amp;s_from=input&amp;amp;query=%E7%BC%96%E7%A8%8B%E5%B0%8F%E7%99%BD&amp;#43;AI&amp;amp;ie=utf8&amp;amp;_sug_=y&amp;amp;_sug_type_=&amp;amp;w=01019900&amp;amp;sut=6626&amp;amp;sst0=1731470669943&amp;amp;lkt=3%2C1731470667727%2C1731470669841">吸睛话题&lt;/a>：&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>编程小白用 AI 编程，人人都能成为编程高手&lt;/li>
&lt;li>零基础也能跨界开发&lt;/li>
&lt;li>编程小白的逆袭：借助 AI 打造 xxx&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>在自媒体的推波助澜下，AI 编程已成为一种潮流，甚至被包装成人人都可掌握的技能。当然，这背后也少不了培训公司借机贩卖焦虑的推动。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/ai-copilot-for-programming/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep Dive Clickstream Analytics Series: Data Pipeline Observability</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/pipeline-observability/</link><pubDate>Mon, 21 Oct 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/pipeline-observability/</guid><description>
&lt;p>In this post, we will explore the observability features of our &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>. Observability is crucial for understanding the health of your data pipeline, identifying issues promptly, and ensuring optimal performance. We'll cover the monitoring, logging, and troubleshooting capabilities built into the solution.&lt;/p>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>The clickstream analytics solution incorporates several observability features to help users monitor and maintain their data pipelines:&lt;/p>
&lt;ol>
&lt;li>Logging&lt;/li>
&lt;li>Custom CloudWatch dashboards&lt;/li>
&lt;li>Automated alerting&lt;/li>
&lt;li>Pipeline health checks&lt;/li>
&lt;li>Troubleshooting tools&lt;/li>
&lt;/ol>
&lt;p>Let's delve into each of these components.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/pipeline-observability/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep Dive Clickstream Analytics Series: Reporting</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/report/</link><pubDate>Sat, 19 Oct 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/report/</guid><description>
&lt;p>In this post, we will explore the reporting module of our &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>. This module leverages &lt;a href="https://aws.amazon.com/quicksight/">Amazon QuickSight&lt;/a> to provide powerful visualization and analysis capabilities for clickstream data, enabling users to gain valuable insights from their data.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/report/">Read More&lt;/a>&lt;/p></description></item><item><title>Using Amazon Bedrock as a Custom OpenAI Server Alternative in Cursor</title><link>https://kane.mx/posts/2024/cursor-meets-bedrock/</link><pubDate>Fri, 11 Oct 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/cursor-meets-bedrock/</guid><description>
&lt;p>&lt;a href="https://www.cursor.com/">Cursor&lt;/a> is a powerful AI-assisted programming Integrated Development Environment (IDE) that comes with built-in Large Language Model (LLM) capabilities to aid in coding. With the introduction of &lt;a href="https://aws.amazon.com/bedrock/">Amazon's Bedrock&lt;/a> Claude 3.5 model, developers now have access to advanced alternatives. In this post, we'll explore how to set up a custom gateway for Amazon Bedrock with the Claude Sonnet 3.5 foundation model and use it in Cursor as a custom model provider. This approach allows us to harness the cutting-edge language model capabilities of Amazon Bedrock within the familiar Cursor environment, potentially offering enhanced performance and cost-effectiveness for AI-assisted coding tasks.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/cursor-meets-bedrock/">Read More&lt;/a>&lt;/p></description></item><item><title>Access Bedrock Claude 3/3.5 Models with Alfred OpenAI ChatGPT Workflow</title><link>https://kane.mx/posts/2024/alfred-integration-with-bedrock-claude/</link><pubDate>Thu, 10 Oct 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/alfred-integration-with-bedrock-claude/</guid><description>
&lt;p>Many &lt;a href="https://www.alfredapp.com/">Alfred&lt;/a> users enjoy the convenience of &lt;a href="https://www.alfredapp.com/workflows/">the OpenAI ChatGPT workflow&lt;/a> for quick AI-powered assistance. However, with the introduction of &lt;a href="https://aws.amazon.com/bedrock/?nc1=h_ls">Amazon's Bedrock&lt;/a> Claude 3 and 3.5 models, some may want to leverage these powerful alternatives. In this post, we'll explore how to set up a custom gateway to access Bedrock Claude models instead of the OpenAI API for your Alfred OpenAI workflow.&lt;/p>
&lt;h2 id="why-use-bedrock-claude">Why Use Bedrock Claude?&lt;/h2>
&lt;ol>
&lt;li>Potentially lower costs compared to OpenAI's API&lt;/li>
&lt;li>Access to the latest Claude models&lt;/li>
&lt;li>Data privacy considerations (your data stays within AWS)&lt;/li>
&lt;li>Integration with other AWS services&lt;/li>
&lt;/ol>
&lt;h2 id="setting-up-the-bedrock-access-gateway">Setting Up the Bedrock Access Gateway&lt;/h2>
&lt;p>&lt;a href="https://github.com/aws-samples/bedrock-access-gateway">Bedrock Access Gateway&lt;/a> provides OpenAI-compatible RESTful APIs for Amazon Bedrock. It supports streaming responses via server-sent events (SSE) and is compatible with various Bedrock model families, including Anthropic Claude 3 (Haiku/Sonnet/Opus), Claude 3.5 Sonnet, Meta Llama 3, Mistral, and more features.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/alfred-integration-with-bedrock-claude/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep dive clickstream analytic series: Data Modeling</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/</link><pubDate>Sun, 22 Sep 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/</guid><description>
&lt;p>In this post, we will delve into the data modeling module of our &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>. This module is an optional component that creates data models in the &lt;a href="https://aws.amazon.com/redshift/">Amazon Redshift&lt;/a> data warehouse and calculates reporting dimensions based on the event, session, and user factor tables generated in the &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/">data processing module&lt;/a>.&lt;/p>
&lt;h2 id="overview-architecture">Overview Architecture&lt;/h2>
&lt;p>
&lt;figure>
&lt;picture>
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/images/architecture.avif" type="image/avif">
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/images/architecture.webp" type="image/webp">
&lt;img
loading="lazy"
decoding="async"
alt="Overview architecture"
class="image_figure image_internal image_processed"
width="1000"
height="777"
src="https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/images/architecture.png"
title="Overview architecture for data modeling module"
/>&lt;figcaption class="caption_figure caption_internal">Overview architecture for data modeling module&lt;/figcaption>&lt;/picture>
&lt;/figure>
&lt;/p>
&lt;p>The overview architecture demonstrates how the solution orchestrates loading clickstream data into the Amazon Redshift data warehouse and triggers data modeling within Redshift.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/data-modeling/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep dive clickstream analytic series: Data Processing</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/</link><pubDate>Sat, 14 Sep 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/</guid><description>
&lt;p>In this post, we will delve into the data processing module of our &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>. This module is an optional component that normalizes raw clickstream events by cleaning, transforming, and enriching them to fit the standard clickstream data schema defined in the solution. It's designed for flexibility, reliability, high performance, and cost-effectiveness.&lt;/p>
&lt;h2 id="overview-architecture">Overview Architecture&lt;/h2>
&lt;p>
&lt;figure>
&lt;picture>
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/images/architecture.avif" type="image/avif">
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/images/architecture.webp" type="image/webp">
&lt;img
loading="lazy"
decoding="async"
alt="Overview architecture"
class="image_figure image_internal image_processed"
width="921"
height="401"
src="https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/images/architecture.png"
title="Overview architecture for data process module"
/>&lt;figcaption class="caption_figure caption_internal">Overview architecture for data process module&lt;/figcaption>&lt;/picture>
&lt;/figure>
&lt;/p>
&lt;p>The data processing is designed for batch or micro-batch data processing to optimize performance and cost-effectiveness. It's primarily an Apache Spark application running on &lt;a href="https://aws.amazon.com/emr/serverless/">Amazon EMR Serverless&lt;/a> to achieve a balance between high performance and cost. It offers the following capabilities:&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/data-processing/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep dive clickstream analytic series: Data Ingestion</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/</link><pubDate>Sun, 08 Sep 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/</guid><description>
&lt;p>In this post, we will delve into the data ingestion service of our &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>. This service is a vital part of the clickstream analytics system. It is designed to be reliable, resilient, high-performing, flexible, and cost-effective. It plays a key role in capturing clickstream data from various sources and delivering it to downstream processing and modeling components.&lt;/p>
&lt;h2 id="overview-architecture">Overview Architecture&lt;/h2>
&lt;p>
&lt;figure>
&lt;picture>
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/images/architecture.avif" type="image/avif">
&lt;source srcset="https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/images/architecture.webp" type="image/webp">
&lt;img
loading="lazy"
decoding="async"
alt="Overview architecture"
class="image_figure image_internal image_processed"
width="1000"
height="458"
src="https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/images/architecture.png"
title="Overview architecture for data ingestion service"
/>&lt;figcaption class="caption_figure caption_internal">Overview architecture for data ingestion service&lt;/figcaption>&lt;/picture>
&lt;/figure>
&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/data-ingestion/">Read More&lt;/a>&lt;/p></description></item><item><title>Deep dive clickstream analytic series: Serverless web console</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/web-console/</link><pubDate>Wed, 04 Sep 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/web-console/</guid><description>
&lt;p>This post explores the &lt;a href="https://docs.aws.amazon.com/solutions/latest/clickstream-analytics-on-aws/how-the-solution-works.html#web-console">web console&lt;/a> module of the &lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">clickstream solution&lt;/a>.&lt;/p>
&lt;p>The web console allows users to create and manage projects with their data pipeline, which ingests, processes, analyzes, and visualizes clickstream data. In version 1.1, the &lt;a href="https://docs.aws.amazon.com/solutions/latest/clickstream-analytics-on-aws/analytics-studio.html">Analytics Studio&lt;/a> was introduced for &lt;strong>business analysts&lt;/strong>, enabling them to view metrics dashboards, explore clickstream data, design customized dashboards, and manage metadata without requiring in-depth knowledge of data warehouses and SQL.&lt;/p>
&lt;h2 id="one-code-base-for-different-architectures">One code base for different architectures&lt;/h2>
&lt;p>The web console is a web application built using AWS serverless technologies, as demonstrated in the &lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/intro/">Build serverless web application with AWS Serverless&lt;/a> series.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/web-console/">Read More&lt;/a>&lt;/p></description></item><item><title>How to build a clickstream analytic system for small businesses to large-scale events</title><link>https://kane.mx/posts/deep-dive-clickstream-analytics/preface/</link><pubDate>Tue, 03 Sep 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/deep-dive-clickstream-analytics/preface/</guid><description>
&lt;p>In the last couple of months, I led a team to build a comprehensive and open-sourced &lt;a href="https://aws.amazon.com/solutions/implementations/clickstream-analytics-on-aws/">solution&lt;/a> that helps customers analyze clickstream events on the cloud. The solution provides data autonomy, allowing users full access to raw data, near real-time ingestion, flexible configurations, and cost-effectiveness. It is a system that utilizes serverless services to cater to various customers, whether small businesses or large-scale events with massive data volumes, offering fully managed services with minimal operational efforts or the flexibility to use preferred open-source technical stacks.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/deep-dive-clickstream-analytics/preface/">Read More&lt;/a>&lt;/p></description></item><item><title>Analyzing Clickstream Events Using Amazon Athena UDFs</title><link>https://kane.mx/posts/2024/analyzing-clickstream-events-using-amazon-athena-udfs/</link><pubDate>Sat, 17 Aug 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/analyzing-clickstream-events-using-amazon-athena-udfs/</guid><description>
&lt;p>In today's digital age, businesses are constantly seeking ways to understand and analyze user behavior on their websites. Clickstream events provide valuable insights into how users interact with a website, and analyzing this data can help businesses make informed decisions to improve user experience and drive conversions.&lt;/p>
&lt;p>&lt;a href="https://aws.amazon.com/solutions/implementations/clickstream-analytics-on-aws/">Clickstream Analytics on AWS&lt;/a> collects, ingests, analyzes, and visualizes clickstream events from your websites and mobile applications. The solution manages an &lt;a href="https://docs.aws.amazon.com/solutions/latest/clickstream-analytics-on-aws/ingestion-endpoint.html">ingestion endpoint&lt;/a> to receive clickstream events, which are multiple events in a batch sent by the solution‘s SDKs.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/analyzing-clickstream-events-using-amazon-athena-udfs/">Read More&lt;/a>&lt;/p></description></item><item><title>Scan Your Code with Ephemeral SonarQube in GitHub Actions</title><link>https://kane.mx/posts/2024/scan-your-code-with-ephemeral-sonarqube-in-github-actions/</link><pubDate>Sun, 12 May 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/scan-your-code-with-ephemeral-sonarqube-in-github-actions/</guid><description>
&lt;p>As developers, we all know the importance of maintaining high code quality standards. One powerful tool that can help us achieve this is &lt;a href="https://www.sonarsource.com/products/sonarqube/">SonarQube&lt;/a>, a renowned platform for continuous code quality inspection. However, setting up and maintaining a dedicated SonarQube instance can be a cumbersome task, requiring significant resources and ongoing maintenance.&lt;/p>
&lt;p>Fortunately, GitHub Actions offers a convenient solution by allowing us to spin up an ephemeral (short-lived) SonarQube instance directly within our workflow. This approach streamlines the process, eliminating the need for a permanent SonarQube server while still reaping the benefits of its code analysis capabilities.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/scan-your-code-with-ephemeral-sonarqube-in-github-actions/">Read More&lt;/a>&lt;/p></description></item><item><title>Avoiding Pitfalls When Using Amazon DynamoDB Interface VPC Endpoints</title><link>https://kane.mx/posts/2024/dynamodb-interface-vpc-endpoint/</link><pubDate>Sat, 04 May 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/dynamodb-interface-vpc-endpoint/</guid><description>
&lt;p>&lt;a href="https://aws.amazon.com/about-aws/whats-new/2024/03/amazon-dynamodb-aws-privatelink/">Amazon DynamoDB now supports AWS PrivateLink&lt;/a> as of March 19, 2024. This feature allows you to securely access DynamoDB from your Amazon Virtual Private Cloud (VPC) without exposing your traffic to the public internet.&lt;/p>
&lt;p>However, unlike &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html#interface-endpoints">VPC endpoints&lt;/a> for other AWS managed services, the AWS PrivateLink for Amazon DynamoDB does not support the &lt;a href="https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-share-your-services.html#endpoint-service-private-dns">Private DNS&lt;/a> feature. This means that if your subnets are configured with only a DynamoDB Interface VPC endpoint, the public DNS name of the DynamoDB service (e.g., &lt;code>dynamodb.us-east-1.amazonaws.com&lt;/code> in the &lt;code>us-east-1&lt;/code> region) cannot be resolved in those subnets.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/dynamodb-interface-vpc-endpoint/">Read More&lt;/a>&lt;/p></description></item><item><title>Redshift Serverless: Cost Deep Dive and Use Cases</title><link>https://kane.mx/posts/2024/redshift-serverless-cost-deep-dive/</link><pubDate>Sat, 24 Feb 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/redshift-serverless-cost-deep-dive/</guid><description>
&lt;p>Serverless computing is all the rage, promising pay-as-you-go magic and freedom from infrastructure woes. But what about serverless for data warehouses? Let's delve into the fascinating (and sometimes confusing) world of &lt;strong>&lt;a href="https://aws.amazon.com/redshift/redshift-serverless/">Redshift Serverless&lt;/a>&lt;/strong>: its cost structure, ideal use cases, and situations where it might not be the best fit.&lt;/p>
&lt;h2 id="cost-breakdown-beyond-the-illusion-of-free">Cost Breakdown: Beyond the Illusion of Free&lt;/h2>
&lt;p>Redshift Serverless offers a compelling promise: only pay for what you use. But like any good magic trick, there's more to the story. Here's the primary cost breakdown:&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/redshift-serverless-cost-deep-dive/">Read More&lt;/a>&lt;/p></description></item><item><title>Custom compliance implementation in AWS CDK</title><link>https://kane.mx/posts/2024/custom-compliance-for-aws-cdk/</link><pubDate>Tue, 09 Jan 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/custom-compliance-for-aws-cdk/</guid><description>
&lt;p>&lt;a href="https://aws.amazon.com/cdk/?nc1=h_ls">AWS CDK&lt;/a> accelerates cloud development using common programming languages to model your applications. I had a series of posts using CDK to demonstrate &lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/intro/">Building serverless web applications with AWS Serverless&lt;/a>. Because CDK uses a programming language to model your application, you can encapsulate your library via &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/constructs.html">Constructs&lt;/a>, and then reuse it crossing the entire application.&lt;/p>
&lt;p>Meanwhile, you can create your own constructs to encapsulate the compliance requirements to simplify the code. For example, in our solution, I used the construct &lt;code>SolutionFunction&lt;/code> to force using the same Node.js version(18.x), architecture(ARM64), Lambda logging configuration(JSON log), environment variables for &lt;a href="https://docs.powertools.aws.dev/lambda/typescript/latest/core/logger/">Powertools Logger&lt;/a> and so on crossing all &lt;code>NodejsFunction&lt;/code>. In addition, using &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/aspects.html">Aspects&lt;/a> and &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html">escape hatches&lt;/a> to make sure the application meets the compliance requirements.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/custom-compliance-for-aws-cdk/">Read More&lt;/a>&lt;/p></description></item><item><title>Awesome AWS CLI</title><link>https://kane.mx/posts/2024/awscli-collection/</link><pubDate>Sun, 07 Jan 2024 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2024/awscli-collection/</guid><description>
&lt;blockquote>
&lt;p>&lt;strong>Disclaimer&lt;/strong>: the cover image was generated by Amazon Bedrock's Titan Image Generator G1.&lt;/p>&lt;/blockquote>
&lt;p>&lt;a href="https://aws.amazon.com/cli/">AWS CLI&lt;/a> is a swiss knife for orchestrating the operations of AWS resources. Especially, the filter option could help your filter and transform the output then combine with other Linux commands together.&lt;/p>
&lt;p>This post collects the CLI usages to resolve my AWS operation needs.&lt;/p>
&lt;h3 id="delete-the-legacy-versions-of-a-service-catalog-product">Delete the legacy versions of a service catalog product&lt;/h3>
&lt;p>AWS Service Catalog has &lt;a href="https://docs.aws.amazon.com/servicecatalog/latest/adminguide/limits.html">default 100 versions per product&lt;/a>. Below is a one line command to delete the legacy versions.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2024/awscli-collection/">Read More&lt;/a>&lt;/p></description></item><item><title>Build serverless web application with AWS Lambda web adapter</title><link>https://kane.mx/posts/2023/build-serverless-web-application-with-aws-lambda-web-adapter/</link><pubDate>Thu, 26 Oct 2023 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2023/build-serverless-web-application-with-aws-lambda-web-adapter/</guid><description>
&lt;blockquote>
&lt;p>&lt;strong>Disclaimer&lt;/strong>: the cover image was generated by StableDiffusionXL with prompts 'cover image, spring boot, flask framework running in aws lambda'.&lt;/p>&lt;/blockquote>
&lt;p>When deploying and operating a web application on the cloud, you prefer to use your favorite programming language and web framework. Also, you want to benefit from Serverless technologies for stability, scalability, cost optimization, and operation excellence.&lt;/p>
&lt;p>&lt;a href="https://github.com/awslabs/aws-lambda-web-adapter">AWS Lambda Web Adapter&lt;/a> is a tool that perfectly meets your expectations. It lifts and shifts the web application based on your preferred language and web framework, including FastAPI, Flask, Django, Express.js, Next.js, Spring Boot, Nginx, PHP, Rust, Golang Gin, Laravel, ASP.NET, and so on! You don't have to change any code to migrate your application to Lambda runtime. It also supports WebSocket and streaming features that work well with your LLM applications.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2023/build-serverless-web-application-with-aws-lambda-web-adapter/">Read More&lt;/a>&lt;/p></description></item><item><title>Verbose logging for AWS JS SDK v3</title><link>https://kane.mx/posts/2023/aws-js-sdk-v3-verbose-logging/</link><pubDate>Sun, 10 Sep 2023 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2023/aws-js-sdk-v3-verbose-logging/</guid><description>
&lt;p>When programming with the AWS SDK, developers sometimes want to debug a specific HTTP request when invoking an SDK API. Due to the &lt;a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-types/Interface/LoggerOptions/">poor documentation&lt;/a> of AWS JS SDK v3, it takes a lot of work to find a way to print the verbose logging of AWS SDK by asking it to the LLMs.&lt;/p>
&lt;p>Below is a practical tip for enabling verbose logging for AWS JS SDK v3.&lt;/p>
&lt;h3 id="solution-1---specify-a-custom-logger-for-aws-sdk-clients">Solution 1 - specify a custom logger for AWS SDK clients&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">DescribeParametersCommand&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">SSMClient&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s2">&amp;#34;@aws-sdk/client-ssm&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="kr">as&lt;/span> &lt;span class="nx">log4js&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s2">&amp;#34;log4js&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="nx">log4js&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">configure&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> &lt;span class="nx">appenders&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">out&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kr">type&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;stdout&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> &lt;span class="nx">categories&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="k">default&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">appenders&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;out&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">level&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;debug&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">logger&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">log4js&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">getLogger&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">ssmClient&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">SSMClient&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> &lt;span class="nx">logger&lt;/span>: &lt;span class="kt">logger&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;h3 id="solution-2---use-middleware-to-hook-the-life-cyele-of-request">Solution 2 - use middleware to hook the life cyele of request&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">DescribeParametersCommand&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">SSMClient&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s2">&amp;#34;@aws-sdk/client-ssm&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">logRequestMiddleware&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">next&lt;/span>: &lt;span class="kt">any&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">_context&lt;/span>: &lt;span class="kt">any&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="kr">async&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">args&lt;/span>: &lt;span class="kt">any&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Request:&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">args&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">request&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">next&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">args&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">ssmClient&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">SSMClient&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="nx">ssmClient&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">middlewareStack&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">logRequestMiddleware&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">step&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;finalizeRequest&amp;#39;&lt;/span> &lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>See complete working example gist below,&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2023/aws-js-sdk-v3-verbose-logging/">Read More&lt;/a>&lt;/p></description></item><item><title>Define your API via OpenAPI definition on AWS</title><link>https://kane.mx/posts/2022/import-oas-as-api-on-aws/</link><pubDate>Thu, 27 Oct 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/import-oas-as-api-on-aws/</guid><description>
&lt;p>Application Programming Interfaces(APIs) is a critical part of the web service, Werner Vogel, the CTO of AWS had a great
&lt;a href="https://thenewstack.io/werner-vogels-6-rules-for-good-api-design/">6 Rules for Good API Design&lt;/a> presentation in 2021 re:Invent keynote.&lt;/p>
&lt;p>In AWS the developers could manage and proxy the APIs via &lt;a href="https://aws.amazon.com/api-gateway/">Amazon API Gateway&lt;/a>. The developers can use
console, CLI, API or IaC code(for example, Terraform/CloudFormation/CDK) to provisioning the API resources on AWS.
However some developers might flavor with using &lt;a href="https://oai.github.io/Documentation/">OpenAPI specification&lt;/a> to define the APIs. It enables multiple services/tools
to understand the APIs' specification, such as Postman. Amazon API Gateway supports this use case, you can import the
existing OpenAPI definition as API.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/import-oas-as-api-on-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>Setup DevOps pipeline with few code</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/devops-pipeline/</link><pubDate>Wed, 14 Sep 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/devops-pipeline/</guid><description>
&lt;p>DevOps pipeline is a key component of project operation,
it helps you automate steps in your software delivery process.&lt;/p>
&lt;p>Amazon itself has rich expirence on DevOps with large scale services,
it &lt;a href="https://aws.amazon.com/builders-library/?nc1=h_ls&amp;amp;cards-body.sort-by=item.additionalFields.sortDate&amp;amp;cards-body.sort-order=desc&amp;amp;awsf.filter-content-category=content-category%23software-delivery-operations&amp;amp;awsf.filter-content-type=*all&amp;amp;awsf.filter-content-level=*all">shares the lesson and learn&lt;/a> from operating the Amazon's services.
You can read &lt;a href="https://kane.mx/posts/2020/the-best-practise-of-deployment-at-amazon/">this summary post&lt;/a> written in Chinese.&lt;/p>
&lt;p>Also AWS provides fully managed SaaS services for the lifecycle of software development, including
&lt;a href="https://aws.amazon.com/codepipeline/">AWS CodePipeline&lt;/a> for automating continuous delivery pipelines,
&lt;a href="https://aws.amazon.com/codecommit/">AWS CodeCommit&lt;/a> for securely hosting highly scalable private Git repositories,
&lt;a href="https://aws.amazon.com/codeartifact/">AWS CodeArtifact&lt;/a> for artifact management,
&lt;a href="https://aws.amazon.com/codebuild/">AWS CodeBuild&lt;/a> for building and testing code with continuous scaling and
&lt;a href="https://aws.amazon.com/codedeploy/">AWS CodeDeploy&lt;/a> for automating code deployments to maintain application uptime.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/devops-pipeline/">Read More&lt;/a>&lt;/p></description></item><item><title>Federated OIDC login with Cognito and Amplify</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/federated-oidc-login-with-cognito-and-amplify/</link><pubDate>Mon, 12 Sep 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/federated-oidc-login-with-cognito-and-amplify/</guid><description>
&lt;p>When working on either 2C application or 2B service, the customers do not want to
or is not allowed to sign up the new account, they can login the application via existing
IdP or enterprise SSO. So, building the application supports the federated OIDC login
to address such requirements.&lt;/p>
&lt;p>This post extends the capability of &lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/protect-website-with-cognito/">Todolist application protected by Amazon Cognito&lt;/a>,
using &lt;a href="https://auth0.com/">Auth0&lt;/a> as the third party &lt;a href="https://en.wikipedia.org/wiki/OpenID">OpenID Connect&lt;/a> provider introduces the external user pool.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/federated-oidc-login-with-cognito-and-amplify/">Read More&lt;/a>&lt;/p></description></item><item><title>Protect website with Cognito</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/protect-website-with-cognito/</link><pubDate>Sun, 04 Sep 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/protect-website-with-cognito/</guid><description>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/static-website/">Previous post&lt;/a> we demonstrated how distributing and securely deploying the website to global end users.
The authentication and authorization are always mandatory features of web application.
&lt;a href="https://aws.amazon.com/cognito/">Amazon Cognito&lt;/a> is a managed AWS serverless service helping the applications to implement AuthN and AuthZ,
with Cognito the applications securely scales to millions of users(up to 50,000 free users)
supporting identity and access management standards, such as OAuth 2.0, SAML 2.0, and OpenID Connect.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/protect-website-with-cognito/">Read More&lt;/a>&lt;/p></description></item><item><title>Distribute the website globally</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/static-website/</link><pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/static-website/</guid><description>
&lt;p>It's a well known pattern to distribute the website via CDN globally,
it reduces the latency of the site and improve the availibity and security leveraging the infrastructure of cloud provider.&lt;/p>
&lt;p>Using CDN service &lt;a href="https://aws.amazon.com/cloudfront/">CloudFront&lt;/a> and simple storage &lt;a href="https://aws.amazon.com/s3/">S3&lt;/a> on AWS hosts the static website.
It well fits the SPA(single page application) framework technologies, for example, React, Vue and Angularjs.
There are lots of existing project and code snippets to sharing this pattern,
such as &lt;a href="https://serverlessland.com/patterns/cloudfront-s3-lambda-cdk">CloudFront to S3 and API Gateway&lt;/a> and &lt;a href="https://github.com/cdk-patterns/serverless/blob/main/s3-react-website/README.md">AWS S3 / React Website Pattern&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/static-website/">Read More&lt;/a>&lt;/p></description></item><item><title>Build no code restful HTTP API with API Gateway and DynamoDB</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/restful-api/</link><pubDate>Sat, 27 Aug 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/restful-api/</guid><description>
&lt;p>Most web applications are using &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer">Restful APIs&lt;/a> to interactive with the backend services.
In the TODO application, it's the straight forward to get, update and delete the items from backend database.
&lt;a href="https://aws.amazon.com/dynamodb/">Amazon DynamoDB&lt;/a> is a key-value database, it fits for this scenario with scalability and optimized pay-as-you-go cost.
Also &lt;a href="https://aws.amazon.com/api-gateway/">Amazon API Gateway&lt;/a> has built-in integration with AWS serivces, the restful API can be transformed to
the request to DynamoDB APIs. Using this combination you can provide the restful APIs only provisioning AWS resources
without writing the CRUD code!&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/restful-api/">Read More&lt;/a>&lt;/p></description></item><item><title>Build serverless web application with AWS Serverless</title><link>https://kane.mx/posts/2022/build-serverless-app-on-aws/intro/</link><pubDate>Fri, 26 Aug 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/build-serverless-app-on-aws/intro/</guid><description>
&lt;p>Building web application is a common use case, leveraging cloud services could accelerate
the builders to develop and deploy the services. With AWS serverless services,
the application can easily get the capabilities like security, highly availability,
scalability, resiliency and cost optimized.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/build-serverless-app-on-aws/intro/">Read More&lt;/a>&lt;/p></description></item><item><title>FluxCD GitOps debugging tip</title><link>https://kane.mx/posts/gitops/fluxcd-local-debug-tip/</link><pubDate>Thu, 16 Jun 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/fluxcd-local-debug-tip/</guid><description>
&lt;p>After enabling E2E testing of FluxCD powered GitOps continuous deployment, the feedback of new commits are quite slow.
Because you have to wait for the E2E testing result, lots of time cost on setuping the environment and provisioning
your development from scrath.&lt;/p>
&lt;p>Inspired by &lt;a href="https://github.com/zxkane/eks-gitops/actions/workflows/e2e.yaml">E2E testing in Github actions&lt;/a>, the DevOps engineers can build local debugging environment in
&lt;a href="https://kind.sigs.k8s.io/">Kind&lt;/a> or &lt;a href="https://minikube.sigs.k8s.io/docs/start/">minikube&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/fluxcd-local-debug-tip/">Read More&lt;/a>&lt;/p></description></item><item><title>使用外部Secrets Manager管理Kubernetes密钥</title><link>https://kane.mx/posts/gitops/manage-k8s-secrets-in-external-secrets-manager/</link><pubDate>Sun, 12 Jun 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/manage-k8s-secrets-in-external-secrets-manager/</guid><description>
&lt;h2 id="背景">背景&lt;/h2>
&lt;p>密钥的管理对于使用 GitOps 方式做持续发布是一个挑战，特别是当目标部署平台是 Kubernetes 的时候。
K8S 使用声明式配置管理最终状态，而&lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/">K8S中的密钥&lt;/a>仅仅是将密钥内容做了&lt;a href="https://en.wikipedia.org/wiki/Base64">base64&lt;/a>格式的编码。
在&lt;a href="https://kane.mx/posts/gitops/flux-in-action-1/">基于 Flux 的 GitOps 实战&lt;/a>介绍了使用&lt;a href="https://kane.mx/posts/gitops/flux-in-action-1/#3-密钥的管理">Bitnami Sealed Secrets&lt;/a>加密密钥内容，
可以安全的将加密后的Kubernetes Manifest文件提交到Git代码仓库，由Sealed Secrets发现这些SealedSecret的密码，
并解密后动态的创建K8S原生Secrets对象。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/manage-k8s-secrets-in-external-secrets-manager/">Read More&lt;/a>&lt;/p></description></item><item><title>基于 Flux 的 GitOps 管理 Crossplane 部署及资源</title><link>https://kane.mx/posts/gitops/crossplane-meets-gitops/</link><pubDate>Wed, 01 Jun 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/crossplane-meets-gitops/</guid><description>
&lt;h2 id="背景">背景&lt;/h2>
&lt;p>在&lt;a href="https://kane.mx/posts/gitops/flux-in-action-2/#六小结及展望">Flux 部署实战的总结展望&lt;/a>中有一个方向是如何将云上基础设施资源同Kubernetes内资源统一管理，
而&lt;a href="https://crossplane.io/">Crossplane&lt;/a>提供了一个高度可扩展的后端，使用声明式程序同时编排应用程序和基础设施，不用关心它们在哪里运行。&lt;/p>
&lt;p>近期 AWS 官方博客宣布了 &lt;a href="https://aws.amazon.com/blogs/opensource/introducing-aws-blueprints-for-crossplane/">AWS Blueprints for Crossplane&lt;/a>，为客户提供了在 &lt;a href="https://aws.amazon.com/eks/">Amazon EKS&lt;/a>
上应用 Crossplane 的参考实现。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/crossplane-meets-gitops/">Read More&lt;/a>&lt;/p></description></item><item><title>Publish your AWS CDK applications via AWS CloudFormation templates</title><link>https://kane.mx/posts/2022/publish-cdk-app-via-cloudformation/</link><pubDate>Sun, 15 May 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/publish-cdk-app-via-cloudformation/</guid><description>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-cdk/">AWS CDK&lt;/a> is a great abstract to accelerate managing the cloud infrastructure as code.
The journey will be enjoyful with leveraging the &lt;a href="https://constructs.dev/">Construct Hub&lt;/a> to use the high level contributions from AWS partners and commnunity.&lt;/p>
&lt;h3 id="use-case">Use Case&lt;/h3>
&lt;p>&lt;a href="https://aws.amazon.com/cloudformation/?nc1=h_ls">AWS CloudFormation&lt;/a> is one of the underly technologies of AWS CDK to manage the cloud infrastructure.
It easily to enable the IT administrators even business operators whom has no/limited developer skills to
develop the &lt;a href="https://aws.amazon.com/solutions/browse-all/">end-to-end solutions&lt;/a> with one-click user experience.&lt;/p>
&lt;p>So it's a use case for effectively developing the &lt;strong>Cloud Application&lt;/strong> via AWS CDK,
then publishing it as CloudFormation template with better user experimental experience.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/publish-cdk-app-via-cloudformation/">Read More&lt;/a>&lt;/p></description></item><item><title>基于 Flux 的 GitOps 实战（下）</title><link>https://kane.mx/posts/gitops/flux-in-action-2/</link><pubDate>Sun, 08 May 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/flux-in-action-2/</guid><description>
&lt;p>在&lt;a href="https://kane.mx/posts/gitops/flux-in-action-1/">上篇&lt;/a>介绍基于 CNCF 下的 GitOps 工具 FluxCD v2
实现了管理多账户的 Kubernetes 集群的共享组件，Secrets 使用的最佳实践，
GitOps 流水线事件同 IM(Slack) 的集成，以及对 GitOps 代码的 CI 流程。&lt;/p>
&lt;p>本文将围绕如何使用 Flux 的多租户管理最佳实践，打造基于 GitOps 工作流程的共享服务平台，
实现租户(业务/应用团队)可自助的持续部署。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/flux-in-action-2/">Read More&lt;/a>&lt;/p></description></item><item><title>基于 Flux 的 GitOps 实战（上）</title><link>https://kane.mx/posts/gitops/flux-in-action-1/</link><pubDate>Fri, 22 Apr 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/flux-in-action-1/</guid><description>
&lt;p>在&lt;a href="https://kane.mx/posts/gitops/the-best-practise-of-gitops-in-kubernetes/">前文&lt;/a>介绍了 GitOps 的概念，Kubernetes 上 GitOps 最佳实践以及对比了 CNCF 基金会下
云原生的 GitOps 工具（ArgoCD 和 Flux）。本篇将带你按照 Flux 的最佳实践在跨VPC跨账户的 Kubernetes
上实践 GitOps 的持续集成，轻松管理数十数百乃至更多的集群及部署在上面的应用。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/flux-in-action-1/">Read More&lt;/a>&lt;/p></description></item><item><title>Kuberentes 上 GitOps 最佳实践</title><link>https://kane.mx/posts/gitops/the-best-practise-of-gitops-in-kubernetes/</link><pubDate>Wed, 30 Mar 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/gitops/the-best-practise-of-gitops-in-kubernetes/</guid><description>
&lt;p>今天 Kuberentes 已经成为IT基础设施的重要玩家，容器编排领域的事实标准。写于3年前的文章&lt;a href="https://kane.mx/posts/effective-cloud-computing/using-kubernetes-on-cloud/">不要自建 Kuberentes&lt;/a> 的观点已经被绝大多数的企业所认可和接受。&lt;/p>
&lt;p>然而同众多企业接触中发现，企业有很高的意愿采用 Kuberentes 管理工作负载，并且已有大量的企业已经将 Kuberentes 用于生产环境。
但如何对多套不同阶段的 Kuberentes 集群来做持续部署，做到高安全性、权限分离、可审计、保证业务团队的敏捷等需求感到困惑。
目前客户实现方式非常多样，并没有很好的遵循业界的最佳实践。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/gitops/the-best-practise-of-gitops-in-kubernetes/">Read More&lt;/a>&lt;/p></description></item><item><title>Find out the most costly resources in your AWS account</title><link>https://kane.mx/posts/2022/find-out-most-costly-resource-in-your-aws-account/</link><pubDate>Sun, 20 Feb 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/find-out-most-costly-resource-in-your-aws-account/</guid><description>
&lt;p>As a builder in cloud, you might feel confused about which resources cost mostly in your account.&lt;/p>
&lt;p>In AWS, you can quickly find out which services even functionality cost a lot via &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/billing-what-is.html">AWS Billing&lt;/a> or
&lt;a href="https://aws.amazon.com/aws-cost-management/aws-cost-explorer/">AWS Cost Explorer&lt;/a>. However sometimes it sucks on finding out which functions cost mostly if
you have hundreds of Lambda functions, or which metrics/log groups cost mostly in &lt;a href="https://aws.amazon.com/cloudwatch/">Amazon CloudWatch&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/find-out-most-costly-resource-in-your-aws-account/">Read More&lt;/a>&lt;/p></description></item><item><title>Grant federated users accessing kubernetes resources in EKS console</title><link>https://kane.mx/posts/2022/grant-federated-users-accessing-k8s-resources-in-eks-console/</link><pubDate>Wed, 09 Feb 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/grant-federated-users-accessing-k8s-resources-in-eks-console/</guid><description>
&lt;p>Though you're administrator of your AWS account, you probably see below warnings when viewing your cluster in EKS console.&lt;/p>
&lt;blockquote>
&lt;p>Your current user or role does not have access to Kubernetes objects on this EKS cluster.&lt;/p>&lt;/blockquote>
&lt;p>&lt;a href="https://kane.mx/posts/2022/grant-federated-users-accessing-k8s-resources-in-eks-console/">Read More&lt;/a>&lt;/p></description></item><item><title>Publishing npm packages to multiple registries with Projen</title><link>https://kane.mx/posts/2022/publishing-npm-packages-to-multiple-registries-with-projen/</link><pubDate>Fri, 04 Feb 2022 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2022/publishing-npm-packages-to-multiple-registries-with-projen/</guid><description>
&lt;p>&lt;a href="https://constructs.dev/">Construct Hub&lt;/a> is a web portal to collect the &lt;a href="https://docs.aws.amazon.com/cdk/latest/guide/constructs.html">constructs&lt;/a> for &lt;a href="https://kane.mx/posts/2019/aws-cdk/">AWS CDK&lt;/a>, CDK8s and CDKtf.
The construct could support multiple programming languages, such as Javascript/TypeScript, Python, Java and C#.
Actually the construct is developed by TypeScript, then it's compiled as across languages library by &lt;a href="https://aws.github.io/jsii/">jsii&lt;/a>!
Any npm/pypi package with certain tags will be discovered by Construct Hub, the package will be automatically recognized as
construct package and listed in Construct Hub.&lt;/p>
&lt;p>&lt;a href="https://github.com/projen/projen">Projen&lt;/a> is a project generator to create project with simplifying the project configuration to support dependencies management,
building, unit testing, code style linting, CI/CD via Github actions PR and actions. So &lt;a href="https://projen.io/awscdk-construct.html">projen&lt;/a>
supports the construct project out of box, which configures construct project with jsii configuration
that build the construct to across languages library, though publish the packages
to kinds of package registries, such as npmjs, pypi and maven central.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2022/publishing-npm-packages-to-multiple-registries-with-projen/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS上构建共享自服务平台服务去中心化研发团队</title><link>https://kane.mx/posts/2021/shared-service-platform-for-decentralized-developer-teams/</link><pubDate>Sun, 26 Dec 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/shared-service-platform-for-decentralized-developer-teams/</guid><description>
&lt;p>近期在一个 Webinar 分享了如何在 AWS 上服务去中心化研发团队构建共享服务平台，核心观点总结如下，&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/shared-service-platform-for-decentralized-developer-teams/">Read More&lt;/a>&lt;/p></description></item><item><title>应用程序弹性设计</title><link>https://kane.mx/posts/2021/application-resilience/</link><pubDate>Sun, 28 Nov 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/application-resilience/</guid><description>
&lt;p>&lt;a href="https://aws.amazon.com/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&amp;amp;wa-lens-whitepapers.sort-order=desc">AWS架构的完善&lt;/a>(AWS Well-Architected)框架涉及了五大支柱，
其中可靠性支柱要求侧重于确保工作负载在预期的时间内正确、一致地执行其预期功能。
这要求应用程序系统具备弹性设计，可从故障中快速恢复，以便满足业务和客户需求。
然而设计、开发、且验证具备弹性设计的应用程序，对经验和实践能力都有很高的要求。
利用成熟的经验和良好的工具将加快构建符合预期的弹性应用程序。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/application-resilience/">Read More&lt;/a>&lt;/p></description></item><item><title>元宇宙风口下的机会</title><link>https://kane.mx/posts/2021/metaverse/</link><pubDate>Mon, 22 Nov 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/metaverse/</guid><description>
&lt;p>元宇宙是近期的热点话题，近期做了些学习了解，将一些学习内容总结为一个deck。分享如下，&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/metaverse/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS上的混沌工程</title><link>https://kane.mx/posts/2021/chaos-engineering-on-aws/</link><pubDate>Sun, 21 Nov 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/chaos-engineering-on-aws/</guid><description>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Chaos_engineering">混沌工程&lt;/a>是一种帮助系统满足弹性需求的技术，它起源于&lt;a href="https://www.gremlin.com/chaos-monkey/">Netflix的工程实践&lt;/a>，著名的猴子军团。&lt;/p>
&lt;p>AWS一直提倡&lt;a href="https://aws.amazon.com/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&amp;amp;wa-lens-whitepapers.sort-order=desc">架构的完善&lt;/a>(AWS Well-Architected)，混沌工程正是卓越运营和可靠性支柱的实践。
因此在 &lt;a href="https://www.youtube.com/watch?v=yoNeMLj3CHc">re:Invent 2020 AWS发布了Fault Injection Simulator&lt;/a>服务来简化开发者在AWS上的混动工程实践。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/chaos-engineering-on-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>Turn off Filevault on macOS</title><link>https://kane.mx/posts/2021/turn-off-filevault-on-macosx/</link><pubDate>Sun, 31 Oct 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/turn-off-filevault-on-macosx/</guid><description>
&lt;p>I'm trying to upgrade my Macbook Pro to macOS Monterey, however the installation can not be started due to the disk is encrypted by Filevault &amp;#x1f615; I have to turn off Filevault to disable disk encrpytion before installing macOS Monterey.&lt;/p>
&lt;p>I found this &lt;a href="https://support.apple.com/guide/mac-help/turn-off-filevault-encryption-on-mac-mchlp2560/11.0/mac/11.0">support article on how turning off Filevault&lt;/a>, but it does not work at all. There is nothing hint or error message after clicking the option &lt;code>Turn off Filevault&lt;/code>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/turn-off-filevault-on-macosx/">Read More&lt;/a>&lt;/p></description></item><item><title>Mirror Helm Charts to AWS ECR</title><link>https://kane.mx/posts/2021/mirror-helm-chart-to-aws-ecr/</link><pubDate>Mon, 27 Sep 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/mirror-helm-chart-to-aws-ecr/</guid><description>
&lt;p>I met a case to mirror existing &lt;a href="https://helm.sh/">Helm&lt;/a> charts to another repository. It might be caused by network availability or compliance requirements.&lt;/p>
&lt;p>There are multiple ways to host a Helm repository, for example, &lt;a href="https://kane.mx/posts/2020/deploy-sonatype-nexus-oss-on-eks/">Nexus OSS Repository&lt;/a>, &lt;a href="https://harness.io/blog/helm-chart-repo/">Github Pages&lt;/a>, &lt;a href="https://aws.amazon.com/blogs/containers/oci-artifact-support-in-amazon-ecr/">AWS ECR&lt;/a> and so on.&lt;/p>
&lt;p>Amazon Elastic Container Registry (&lt;a href="https://aws.amazon.com/ecr/">Amazon ECR&lt;/a>) is a fully managed container registry that makes it easy to store, manage, share, and deploy your container images and artifacts anywhere. It's built with scale and secure. In my case I'm using this existing service to mirror the Helm charts.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/mirror-helm-chart-to-aws-ecr/">Read More&lt;/a>&lt;/p></description></item><item><title>The practise of Amazon Neptune</title><link>https://kane.mx/posts/2021/the-practise-of-amazon-neptune/</link><pubDate>Fri, 03 Sep 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/the-practise-of-amazon-neptune/</guid><description>
&lt;p>&lt;a href="https://aws.amazon.com/neptune/">Amazon Neptune&lt;/a> is a managed Graph database on AWS, whose compute and storage is decoupled like &lt;a href="https://aws.amazon.com/blogs/database/introducing-the-aurora-storage-engine/">Amazon Aurora&lt;/a>. Neptune leverages popular open-source APIs such as Gremlin and SPARQL, and easily migrate existing applications.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/the-practise-of-amazon-neptune/">Read More&lt;/a>&lt;/p></description></item><item><title>The update of Sonatype Nexus repository OSS on AWS solution</title><link>https://kane.mx/posts/2021/nexus-oss-on-aws-v110-update/</link><pubDate>Thu, 24 Jun 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/nexus-oss-on-aws-v110-update/</guid><description>
&lt;p>Last year I shared the production-ready, cloud native solution to &lt;a href="https://kane.mx/posts/2020/deploy-sonatype-nexus-oss-on-eks/">deploy Sonatype Nexus Repository OSS on AWS&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/nexus-oss-on-aws-v110-update/">Read More&lt;/a>&lt;/p></description></item><item><title>在AWS上快速部署专用的NAT实例</title><link>https://kane.mx/posts/2021/simple-nat-on-aws/</link><pubDate>Fri, 16 Apr 2021 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2021/simple-nat-on-aws/</guid><description>
&lt;p>本方案的起因是，一个源代码托管在Github上的项目fix一个重要的bug后，在AWS上的持续部署流水线一直失败。分析日志后，发现流水线中的数个步骤需要克隆源代码，但是访问Github的网络非常不稳定，这数个流水线任务持续因连接超时，连接拒绝等网络错误而失败。而流水线任务大量使用了CodeBuild, Lambda等AWS托管服务，无法为执行环境配置可靠的网络连接。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2021/simple-nat-on-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>Effective AWS CDK for AWS CloudFormation</title><link>https://kane.mx/posts/2020/effective-aws-cdk-for-aws-cloudformation/</link><pubDate>Wed, 16 Dec 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/effective-aws-cdk-for-aws-cloudformation/</guid><description>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code">Infrastructure as Code&lt;/a> is the trend to manage the resources of application. &lt;a href="https://aws.amazon.com/cloudformation/">AWS CloudFormation&lt;/a> is the managed service offering the IaC capability on AWS &lt;a href="https://aws.amazon.com/blogs/aws/cloudformation-create-your-aws-stack-from-a-recipe/">since 2011&lt;/a>. CloudFormation uses the &lt;a href="https://en.wikipedia.org/wiki/Declarative_programming">declarative language&lt;/a> to manage your AWS resources with the style what you get is what you declare.&lt;/p>
&lt;p>However there are cons of CloudFormation as a declarative language,&lt;/p>
&lt;ul>
&lt;li>the readability and maintenance for applications involving lots of resources&lt;/li>
&lt;li>the reuseable of code, &lt;a href="https://aws.amazon.com/blogs/mt/introducing-aws-cloudformation-modules/">CloudFormation modules&lt;/a> released in re:Invent 2020 might help mitigate it&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-cdk/">AWS CDK&lt;/a> provides the programming way to define the infra in code by your preferred programming languages, such as Typescript, Javascript, Python, Java and C#. AWS CDK will synthesis the code to CloudFormation template, then deploying the stack via AWS CloudFormation service. It benefits the Devops engineers manage the infra on AWS as programming application, having version control, code review, unit testing, integration testing and CI/CD pipelines, the deployment still depends on the mature CloudFormation service to rolling update the resources and rollback when failing.&lt;/p>
&lt;p>For solution development, using CDK indeed improves the productivity then publish the deployment assets as CloudFormation templates.&lt;/p>
&lt;p>Though CDK application can be synthesized to CloudFormation template, there are still some differences blocking the synthesized templates to be deployed across multiple AWS regions.&lt;/p>
&lt;p>This post will share the tips on how effectively writing AWS CDK application then deploying the application by CloudFormation across multiple regions.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/effective-aws-cdk-for-aws-cloudformation/">Read More&lt;/a>&lt;/p></description></item><item><title>亚马逊的部署最佳实践</title><link>https://kane.mx/posts/2020/the-best-practise-of-deployment-at-amazon/</link><pubDate>Sat, 28 Nov 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/the-best-practise-of-deployment-at-amazon/</guid><description>
&lt;p>近期&lt;a href="https://aws.amazon.com/builders-library/">Amazon Builders Library&lt;/a>发布了数篇文章介绍亚马逊如何实践持续部署，同时分享了亚马逊在部署方面的最佳实践。&lt;/p>
&lt;p>这里将这三篇文章核心内容做个概述，方便大家按需细读。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/the-best-practise-of-deployment-at-amazon/">Read More&lt;/a>&lt;/p></description></item><item><title>跨账号跨区域部署AWS CDK编排的应用</title><link>https://kane.mx/posts/2020/deploy-aws-cdk-applications-cross-accounts/</link><pubDate>Wed, 14 Oct 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/deploy-aws-cdk-applications-cross-accounts/</guid><description>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-cdk/">AWS CDK&lt;/a>是编排部署AWS云上资源最佳的工具之一。基于AWS CDK的应用应该如何实践DevOps持续集成和部署呢？&lt;/p>
&lt;p>通常我们有下面几种方法，&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/deploy-aws-cdk-applications-cross-accounts/">Read More&lt;/a>&lt;/p></description></item><item><title>Deploy Sonatype Nexus repository OSS on EKS</title><link>https://kane.mx/posts/2020/deploy-sonatype-nexus-oss-on-eks/</link><pubDate>Tue, 16 Jun 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/deploy-sonatype-nexus-oss-on-eks/</guid><description>
&lt;p>&lt;a href="https://www.sonatype.com/nexus-repository-oss">Sonatype Nexus repository OSS&lt;/a> is an artifact repository that supports most software repositories such as Maven, Pypi, Npmjs, Rubygems, Yum, Apt, Docker registry and etc. In the enterprise Nexus repository is widely used for storing proprietary artifacts and caching the artifacts for speeding up the devops.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/deploy-sonatype-nexus-oss-on-eks/">Read More&lt;/a>&lt;/p></description></item><item><title>无服务器架构的Docker镜像数据分析应用</title><link>https://kane.mx/posts/2020/serverless-docker-images-analytics/</link><pubDate>Mon, 04 May 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/serverless-docker-images-analytics/</guid><description>
&lt;p>近期对Docker镜像做了些数据分析，这里分享一下利用云原生技术快速且低成本的实现任意数量的数据分析。&lt;/p>
&lt;p>之前通过文章介绍了&lt;a href="https://kane.mx/posts/2020/get-docker-image-size-without-pulling-image/">不用拉取Docker镜像就可获取镜像的大小&lt;/a>的一种方法，通过其中的示例脚本，我们可以获取到待分析的原始数据。&lt;/p>
&lt;p>比如&lt;code>nginx&lt;/code>镜像的部分原始数据(csv格式)如下，&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-txt" data-lang="txt">&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:676b8117782d9e8c20af8e1b19356f64acc76c981f3a65c66e33a9874877892a,amd64,linux,null,null,&amp;#34;sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08&amp;#34;,2813316
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:676b8117782d9e8c20af8e1b19356f64acc76c981f3a65c66e33a9874877892a,amd64,linux,null,null,&amp;#34;sha256:6ade829cd166df9b2331da48e3e60342aef9f95e1e45cde8d20e6b01be7e6d9a&amp;#34;,6477096
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:70feed62d5204358ed500463c0953dce6c269a0ebeef147a107422a2c78799a9,arm,linux,v6,null,&amp;#34;sha256:b9e3228833e92f0688e0f87234e75965e62e47cfbb9ca8cc5fa19c2e7cd13f80&amp;#34;,2619936
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:70feed62d5204358ed500463c0953dce6c269a0ebeef147a107422a2c78799a9,arm,linux,v6,null,&amp;#34;sha256:a03f81873d278ad248976b107883f0452d33c6f907ebcdd832a6041f1d33118a&amp;#34;,6080562
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:2ba714ccbdc4c2a7b5a5673ebbc8f28e159cf2687a664d540dcb91d325934f32,arm64,linux,v8,null,&amp;#34;sha256:29e5d40040c18c692ed73df24511071725b74956ca1a61fe6056a651d86a13bd&amp;#34;,2724424
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:2ba714ccbdc4c2a7b5a5673ebbc8f28e159cf2687a664d540dcb91d325934f32,arm64,linux,v8,null,&amp;#34;sha256:806787fcd4f9e2f814506fb53e81b6fb33f9eea04e5b537b31fa5fb601a497ee&amp;#34;,6423816
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:6d6f19360150548bbb568ecd3e1affabbdce0fcc39156e70fbae8a0aa656541a,386,linux,null,null,&amp;#34;sha256:2826c1e79865da7e0da0a993a2a38db61c3911e05b5df617439a86d4deac90fb&amp;#34;,2808418
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:6d6f19360150548bbb568ecd3e1affabbdce0fcc39156e70fbae8a0aa656541a,386,linux,null,null,&amp;#34;sha256:f2ab0e3b0ff04d1695df322540631708c42b0a68925788de2290c9497e44fef3&amp;#34;,6845295
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:c0684c6ee14c7383e4ef1d458edf3535cd62b432eeba6b03ddf0d880633207da,ppc64le,linux,null,null,&amp;#34;sha256:9a8fdc5b698322331ee7eba7dd6f66f3a4e956554db22dd1e834d519415b4f8e&amp;#34;,2821843
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:c0684c6ee14c7383e4ef1d458edf3535cd62b432eeba6b03ddf0d880633207da,ppc64le,linux,null,null,&amp;#34;sha256:30a37aac8b54a38e14e378f5122186373cf233951783587517243e342728a828&amp;#34;,6746511
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:714439fec7e1f55c29b57552213e45c96bbfeefddea2b3b30d7568591966c914,s390x,linux,null,null,&amp;#34;sha256:7184c046fdf17da4c16ca482e5ede36e1f2d41ac8cea9c036e488fd149d6e8e7&amp;#34;,2582859
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1.18.0-alpine,sha256:714439fec7e1f55c29b57552213e45c96bbfeefddea2b3b30d7568591966c914,s390x,linux,null,null,&amp;#34;sha256:214dff8a034aad01facf6cf63613ed78e9d23d9a6345f1dee2ad871d6f94b689&amp;#34;,6569410&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>
&lt;p>各列的含义分别是，&lt;code>镜像tag&lt;/code>, &lt;code>镜像&lt;/code>&lt;a href="https://docs.docker.com/registry/spec/api/#content-digests">Digest&lt;/a>, &lt;code>镜像对应平台的Architecture&lt;/code>, &lt;code>镜像对应平台的OS&lt;/code>, &lt;code>镜像对应平台的变种&lt;/code>（例如，ARM的v7, v8等）, &lt;code>镜像对应平台的OS版本&lt;/code>, &lt;code>镜像组成层的&lt;/code>&lt;a href="https://docs.docker.com/registry/spec/api/#content-digests">Digest&lt;/a>, &lt;code>镜像组成层的大小&lt;/code>。&lt;/p>
&lt;p>上面&lt;code>nginx&lt;/code>镜像的示例数据，告诉我们镜像名&lt;code>nginx&lt;/code>且tag为&lt;code>1.18.0-alpine&lt;/code>的镜像包含了&lt;code>amd64-linux&lt;/code>, &lt;code>arm-linux-v6&lt;/code>, &lt;code>arm64-linux-v8&lt;/code>, &lt;code>386-linux&lt;/code>, &lt;code>ppc64le-linux&lt;/code>以及&lt;code>s390x-linux&lt;/code>共5种Arch合计6个版本的镜像。且每个平台的对应镜像包含了两个层以及这两个层的大小。&lt;/p>
&lt;p>当我们有了成百数千甚至海量镜像的原始数据后，如何能快速且低成本的分析这些数据呢？&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/serverless-docker-images-analytics/">Read More&lt;/a>&lt;/p></description></item><item><title>Get the size of Docker image without pulling image</title><link>https://kane.mx/posts/2020/get-docker-image-size-without-pulling-image/</link><pubDate>Sat, 02 May 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/get-docker-image-size-without-pulling-image/</guid><description>
&lt;p>Recently I had a requirement to stats the size of some Docker images. It would be waste if pulling them all firstly then calculating the size of each image. Also you know the docker image consists of some Docker layers that probably are shared by other images. It's hard to get the disk usage if only sum the size of each image.&lt;/p>
&lt;p>Is there any way to get the size of Docker image without pulling it?&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/get-docker-image-size-without-pulling-image/">Read More&lt;/a>&lt;/p></description></item><item><title>oh-my-zsh性能调优思路</title><link>https://kane.mx/posts/2020/zsh-performance-tuning/</link><pubDate>Wed, 22 Apr 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/zsh-performance-tuning/</guid><description>
&lt;p>&lt;a href="https://zh.wikipedia.org/wiki/Z_shell">Z shell&lt;/a>搭配&lt;a href="https://ohmyz.sh/">oh-my-zsh&lt;/a>自定义配置已成为众多Linux/Macosx用户的标准terminal配置。&lt;/p>
&lt;p>最近遇到在&lt;code>zsh&lt;/code>中执行任意命令都变得特别慢(哪怕简单执行&lt;code>ls&lt;/code>也要花费肉眼可见的1，2秒钟)，这里记录下如何排查&lt;a href="https://zh.wikipedia.org/wiki/Z_shell">Z shell&lt;/a>下启用&lt;a href="https://ohmyz.sh/">oh-my-zsh&lt;/a>的性能问题。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/zsh-performance-tuning/">Read More&lt;/a>&lt;/p></description></item><item><title>基于CodeCommit代码管理的无服务器架构Devops</title><link>https://kane.mx/posts/2020/codecommit-devops-model/</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/codecommit-devops-model/</guid><description>
&lt;p>&lt;a href="https://github.com/">Github&lt;/a>/&lt;a href="https://about.gitlab.com/">Gitlab&lt;/a>已经成为众多开发者非常熟悉的代码协作平台，通过他们参与开源项目或实施企业内部项目协作。&lt;/p>
&lt;p>AWS也提供了托管的、基于Git、安全且高可用的代码服务&lt;a href="https://aws.amazon.com/codecommit/">CodeCommit&lt;/a>。&lt;a href="https://aws.amazon.com/codecommit/">CodeCommit&lt;/a>主要针对企业用户场景，所以他并没有社交功能以及代码仓库fork功能，是否&lt;a href="https://aws.amazon.com/codecommit/">CodeCommit&lt;/a>就无法实现&lt;a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests">Github基于Pull Request&lt;/a>的协同工作模式呢？&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/codecommit-devops-model/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS发布更快、更便宜、更易用的HTTP APIs</title><link>https://kane.mx/posts/2020/new-http-apis-of-api-gateway/</link><pubDate>Fri, 13 Mar 2020 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2020/new-http-apis-of-api-gateway/</guid><description>
&lt;p>AWS在3月12日&lt;a href="https://aws.amazon.com/blogs/compute/building-better-apis-http-apis-now-generally-available/">正式发布了新一代的API网关 -- HTTP APIs&lt;/a>。AWS发布的第一代API Gateway服务已经快5年了，通过这些年来大规模服务客户的心得以及客户反馈，由此重新构建了更快（相比第一代网关60%的延迟减少）、更便宜（至少节省71%的费用）、更易用的第二代网关服务。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2020/new-http-apis-of-api-gateway/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS Cloud Debugging初探</title><link>https://kane.mx/posts/2019/aws-cloud-debugging/</link><pubDate>Thu, 26 Dec 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aws-cloud-debugging/</guid><description>
&lt;p>在&lt;a href="https://reinvent.awsevents.com/?nc2=h_ql_re">re:Invent&lt;/a> 2019之前，&lt;a href="https://aws.amazon.com/getting-started/tools-sdks/?nc2=h_ql_prod_dt_tsdk">AWS Toolkit&lt;/a>发布了&lt;a href="https://aws.amazon.com/about-aws/whats-new/2019/11/announcing-cloud-debugging-beta/?nc1=h_ls">Cloud Debugging beta&lt;/a>功能。该功能支持在IntelliJ IDEs(IntelliJ, PyCharm, Webstorm, 以及 Rider)中远程调试 ECS &lt;a href="https://aws.amazon.com/fargate/">Fargate&lt;/a> 容器中执行的应用程序。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-cloud-debugging/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS Batch简介</title><link>https://kane.mx/posts/2019/aws-batch/</link><pubDate>Wed, 25 Dec 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aws-batch/</guid><description>
&lt;p>&lt;a href="https://aws.amazon.com/batch/">AWS Batch&lt;/a>是一个全托管的批处理调度服务，它可为用户管理所有基础设施，从而避免了预置、管理、监控和扩展批处理计算作业所带来的复杂性。当然&lt;a href="https://aws.amazon.com/batch/">AWS Batch&lt;/a>已与 AWS 平台原生集成，让用户能够利用 AWS 的扩展、联网和访问管理功能。让用户轻松运行能够安全地从 AWS 数据存储（如 Amazon S3 和 Amazon DynamoDB）中检索数据并向其中写入数据的作业。&lt;a href="https://aws.amazon.com/batch/">AWS Batch&lt;/a>可根据所提交的批处理作业的数量和资源要求预置计算资源并优化作业分配。能够将计算资源动态扩展至运行批处理作业所需的任何数量，从而不必受固定容量集群的限制。&lt;a href="https://aws.amazon.com/batch/">AWS Batch&lt;/a>还可以利用 Spot 实例，从而进一步降低运行批处理作业产生的费用。&lt;/p>
&lt;p>&lt;a href="https://aws.amazon.com/batch/">AWS Batch&lt;/a>服务本身是&lt;strong>免费&lt;/strong>的，仅收取实际使用的 EC2 实例费用。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-batch/">Read More&lt;/a>&lt;/p></description></item><item><title>免费邮件转发服务</title><link>https://kane.mx/posts/2019/email-forwarding/</link><pubDate>Wed, 18 Dec 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/email-forwarding/</guid><description>
&lt;p>在拥有域名后，通常希望创建一些自有域名下的邮箱来收取不同用途的邮件，同时不希望为这部分功能付费&amp;#x1f603;。使用免费的企业邮箱(比如网易企业邮箱、阿里云企业邮箱)是一种选择。这时就需要配置邮件地址和邮件客户端来收取邮件，如果有多个邮箱地址，配置会特别麻烦。有时，这些企业邮箱的收件服务会莫名其妙的丢失一些邮件。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/email-forwarding/">Read More&lt;/a>&lt;/p></description></item><item><title>实战Aliyun EDAS应用迁移AWS</title><link>https://kane.mx/posts/2019/aliyun-edas-migration-in-action/</link><pubDate>Mon, 02 Dec 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aliyun-edas-migration-in-action/</guid><description>
&lt;p>近期实践了将阿里云EDAS微服务应用迁移到AWS上，在这里分享一下迁移方案。&lt;/p>
&lt;p>该方案涉及了以下三个方面，&lt;/p>
&lt;ol>
&lt;li>微服务应用集群。在AWS上采用的&lt;a href="https://aws.amazon.com/cn/ecs/">ECS&lt;/a>集群部署微服务应用，通过&lt;a href="https://aws.amazon.com/cn/cloud-map/">Cloudmap&lt;/a>实现服务注册发现，&lt;a href="https://aws.amazon.com/cn/app-mesh/">App Mesh&lt;/a>实现服务间流量控制。更加详尽的微服务迁移要点和对应方案，详见下面的deck。&lt;/li>
&lt;li>Devops pipeline。使用托管的&lt;a href="https://aws.amazon.com/cn/codepipeline/">CodePipeline&lt;/a>，&lt;a href="https://aws.amazon.com/cn/codebuild/">CodeBuild&lt;/a>实现CI/CD。&lt;/li>
&lt;li>Infra as Code。利用AWS强大的&lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code">Infra as Code&lt;/a>能力，将云上的基础设施和微服务应用编排通过&lt;a href="https://kane.mx/posts/2019/aws-cdk/">CDK&lt;/a>代码实现。&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>下面是迁移方案的deck。完整且可部署的PoC代码，点&lt;a href="https://github.com/zxkane/alibabacloud-microservice-demo">这里&lt;/a>。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aliyun-edas-migration-in-action/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS RDS数据库日志分析及展示</title><link>https://kane.mx/posts/2019/rds-log-analysis/</link><pubDate>Tue, 05 Nov 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/rds-log-analysis/</guid><description>
&lt;p>托管的RDS数据库已经是云计算服务中非常成熟的服务，绝大部分的云计算用户会采用RDS服务来提升数据库服务的可用性同时减少数据库的各类运维事务。&lt;/p>
&lt;p>AWS RDS服务支持开启和查询各类的数据库日志，包括常规日志、慢日志、错误日志和审计日志。但RDS服务默认提供的日志查看工具仅仅类似文本查看器，无法针对日志数据做统计和查看历史滚动的存档。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/rds-log-analysis/">Read More&lt;/a>&lt;/p></description></item><item><title>使用Openswan连接AWS VPC</title><link>https://kane.mx/posts/2019/using-openswan-connect-aws-vpn/</link><pubDate>Mon, 16 Sep 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/using-openswan-connect-aws-vpn/</guid><description>
&lt;p>业务上云之后，经常也有需求将多云、数据中心或办公室的私有网络同云端的私有网络建立连接。&lt;a href="https://docs.aws.amazon.com/zh_cn/vpn/latest/s2svpn/VPC_VPN.html">AWS Site-to-Site VPN&lt;/a>正是AWS提供的托管VPN服务，我们可以在另一端的私有网络通过&lt;a href="https://www.openswan.org/">Openswan&lt;/a>同AWS VPC网络建立基于IPSec协议的安全连接。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/using-openswan-connect-aws-vpn/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS CDK简介</title><link>https://kane.mx/posts/2019/aws-cdk/</link><pubDate>Sun, 08 Sep 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aws-cdk/</guid><description>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code">Infrastructure as Code&lt;/a>(架构即代码)一直是衡量公有云是否支持良好运维能力的重要指标。作为云计算领先的AWS，通过服务&lt;a href="https://aws.amazon.com/cn/cloudformation/">CloudFormation&lt;/a>来编排云环境中的基础设施资源。不过由于CloudFormation是使用YAML/JSON编写的声明式语言，不善于处理逻辑，编写繁琐且不利于调试排错，对于新上手的Devops工程师来说也有不小的学习曲线。三方开源的工具&lt;a href="https://en.wikipedia.org/wiki/Terraform_%28software%29">Terraform&lt;/a>同样没有很好解决&lt;a href="https://aws.amazon.com/cn/cloudformation/">CloudFormation&lt;/a>存在的这些问题。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-cdk/">Read More&lt;/a>&lt;/p></description></item><item><title>无服务器架构的域名重定向服务</title><link>https://kane.mx/posts/effective-cloud-computing/serverless-domain-redirect/</link><pubDate>Tue, 27 Aug 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/serverless-domain-redirect/</guid><description>
&lt;p>业务时常有需求将某个域名(A)的访问重定向到其他域名(B)，即使实现这样一个很简单的需求通常也需要部署Web服务器（例如Nginx），为域名A的请求返回302响应，并提供新的Location地址重定向到域名B。现在基于云计算服务，我们可以使用一些托管服务来实现同样的事情，无需管理服务器和维护应用，同时做到最低成本实现该需求。&lt;/p>
&lt;p>接下来将介绍如何利用AWS上的服务实现该需求。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-domain-redirect/">Read More&lt;/a>&lt;/p></description></item><item><title>Amazon Alexa Android版本国内登录问题</title><link>https://kane.mx/posts/2019/alexa-login-issue/</link><pubDate>Wed, 14 Aug 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/alexa-login-issue/</guid><description>
&lt;p>近期需要做一些Alexa上的开发，在手机上安装了Amazon Alexa，一直得到下面这样的错误提示而无法登录。&lt;/p>
&lt;blockquote>
&lt;p>Connection Timed Out.&lt;/p>&lt;/blockquote>
&lt;p>&lt;a href="https://kane.mx/posts/2019/alexa-login-issue/">Read More&lt;/a>&lt;/p></description></item><item><title>使用AWS S3作为MacOSX时间机器(Time Machine)的备份存储</title><link>https://kane.mx/posts/2019/using-s3-as-device-for-mac-time-machine-backup/</link><pubDate>Sun, 30 Jun 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/using-s3-as-device-for-mac-time-machine-backup/</guid><description>
&lt;p>个人电脑数据备份一直都是一个强烈的需求。使用网盘等云存储产品可以部分满足数据的备份需求，仍然无法做到使用便利性和很高的数据安全保障。&lt;/p>
&lt;p>MacOSX上系统内置了备份解决方案 -- &lt;a href="https://support.apple.com/zh-cn/HT201250">时间机器(Time Machine)&lt;/a>。Time Machine支持AirPort Time Capsule，NAS存储或者外置的存储设备。然而这些备份方案都依赖于硬件设备，有容量限制或不便于移动。在云计算已经大行其道的今天，有没有使用云计算厂商对象存储作为目标存储的备份方案，为MacOSX数据备份提供无限容量、高度的安全性的云方案？经过一番搜索，既找到了开源免费的工具&lt;a href="https://restic.net/">Restic&lt;/a>，也有付费软件&lt;a href="https://www.arqbackup.com/">Arq&lt;/a>。无论Restic还是Arq提供的是独立的三方工具来实现备份到云端存储或从云端恢复，有没有将Time Machine和云端储存结合在一起的方案呢？&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/using-s3-as-device-for-mac-time-machine-backup/">Read More&lt;/a>&lt;/p></description></item><item><title>Spring Cloud Function -- 跨Serverless平台的函数计算框架</title><link>https://kane.mx/posts/effective-cloud-computing/spring-cloud-function-for-aws/</link><pubDate>Fri, 28 Jun 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/spring-cloud-function-for-aws/</guid><description>
&lt;p>&lt;a href="https://kane.mx/posts/2019/serverless-framework/">基于serverless框架的钉钉回调函数&lt;/a>中介绍了serverless framework，一款支持跨云厂商/Serverless平台的部署工具。但是函数代码还是需要针对不同的serverless平台作对应的适配。而&lt;a href="https://spring.io/projects/spring-cloud-function">Spring Clound Function&lt;/a>就是针对这种情况专门开发的跨serverless平台的框架，实现一套代码通过不同的打包实现跨serverless平台。Spring Clound Function目前支持AWS Lambda, Microsoft Azure Function以及Apache OpenWhisk。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/spring-cloud-function-for-aws/">Read More&lt;/a>&lt;/p></description></item><item><title>公有云对比</title><link>https://kane.mx/posts/2019/aws-vs-aliyun/</link><pubDate>Wed, 26 Jun 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aws-vs-aliyun/</guid><description>
&lt;p>AWS是全球云计算领域的领跑者，它在计算、存储、网络等方面都做出了很多创新，同时也是其他云计算厂商学习及模仿的对象。&lt;/p>
&lt;p>阿里云是目前国内市场份额最大的云计算厂商，其份额&lt;a href="http://www.sohu.com/a/302064020_465914">超过了第二至五位厂商的总和&lt;/a>，份额领先优势比AWS在全球还要显著，同时&lt;a href="https://www.canalys.com/newsroom/cloud-market-share-q4-2018-and-full-year-2018">全球份额也超过IBM来到第四&lt;/a>。&lt;/p>
&lt;p>本文将对AWS和阿里云核心服务做一个简要对比，以及这两家厂商发展方向的一些个人见解。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-vs-aliyun/">Read More&lt;/a>&lt;/p></description></item><item><title>Serverless framework 101</title><link>https://kane.mx/posts/2019/serverless-framework/</link><pubDate>Thu, 16 May 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/serverless-framework/</guid><description>
&lt;p>&lt;a href="https://serverless.com/">Serverless Framework&lt;/a>是一个开源命令行工具。他提供函数脚手架、流程自动化、最佳实践等帮助开发、部署跨云厂商的托管无服务器计算服务(官方已支持aws, Azure, GCP, IBM Cloud等各种厂商的无服务器计算)。同时支持使用插件来扩展各种功能，比如支持更多云厂商无服务器计算服务，例如&lt;a href="https://github.com/aliyun/serverless-aliyun-function-compute">阿里云的函数计算&lt;/a>。&lt;/p>
&lt;p>这里使用&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/">基于函数计算的钉钉回调函数接口&lt;/a>示例来演示如何使用&lt;a href="https://serverless.com/">Serverless Framework&lt;/a>将一个无服务器函数部署到&lt;a href="https://aws.amazon.com/lambda">AWS Lambda&lt;/a>。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/serverless-framework/">Read More&lt;/a>&lt;/p></description></item><item><title>AWS Lambda Layer实践</title><link>https://kane.mx/posts/2019/aws-lambda-layers/</link><pubDate>Tue, 14 May 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/aws-lambda-layers/</guid><description>
&lt;p>在&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/">基于函数计算的钉钉回调函数接口&lt;/a>中使用钉钉回调函数案例实践了&lt;a href="https://aws.amazon.com/lambda/">AWS Lambda&lt;/a>无服务函数。该示例中，我们将自定义的函数代码及依赖的第三方库（比如json处理库jackson, 钉钉openapi加密库, aws dynamodb client等）整体打包为一个部署包，上传到lamdba代码仓库用于函数执行。&lt;/p>
&lt;p>然而实际项目中，其实有大量的相关函数可能会共享这些基础依赖库、三方函数库(比如headless chrome(Puppeteer), pandoc, OCR library -- Tesseract等等)或者使用自定义runtime(如官方未支持的java11)的需求。AWS Lambda在去年底发布了&lt;a href="https://aws.amazon.com/about-aws/whats-new/2018/11/aws-lambda-now-supports-custom-runtimes-and-layers/">Lambda layers功能&lt;/a>来满足上述这些实际开发中的需求。&lt;/p>
&lt;p>接下来，让我们看看如何将&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/">前文&lt;/a>中的&lt;a href="https://github.com/zxkane/dingtalk-callback-on-aws/blob/267b5f11851148f5a23a834b8b7ecd4d3b247ce7/build.gradle.kts#L71-L91">函数依赖&lt;/a>放置到一个单独的layer中，作为不同函数的共享依赖库。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/aws-lambda-layers/">Read More&lt;/a>&lt;/p></description></item><item><title>QCon2019北京站回顾</title><link>https://kane.mx/posts/2019/2019-qconbeijing-reviews/</link><pubDate>Thu, 09 May 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2019/2019-qconbeijing-reviews/</guid><description>
&lt;p>这周参加了&lt;a href="https://2019.qconbeijing.com/">QCon 2019北京站&lt;/a>，这里记录下部分印象深刻的主题以及个人感受。&lt;/p>
&lt;p>QCon是由InfoQ主办的综合性技术盛会，主题涵盖了大前端、高可用架构、容器技术、大数据、机器学习等各种热门技术主题。其中也不乏&lt;a href="https://2019.qconbeijing.com/track/501">下一代分布式应用&lt;/a>、&lt;a href="https://2019.qconbeijing.com/track/565">混沌工程&lt;/a>等前沿有意思的主题，后面会详细介绍相关的主题演讲。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2019/2019-qconbeijing-reviews/">Read More&lt;/a>&lt;/p></description></item><item><title>Spring Cloud or Cloud Native</title><link>https://kane.mx/posts/effective-cloud-computing/spring-cloud-or-cloud-native/</link><pubDate>Mon, 29 Apr 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/spring-cloud-or-cloud-native/</guid><description>
&lt;p>基于Java的&lt;a href="https://spring.io/projects/spring-cloud">Spring Cloud&lt;/a>是由Java最大开源生态&lt;a href="https://spring.io/">Spring&lt;/a>社区推出的Out-of-Box分布式&lt;a href="https://en.wikipedia.org/wiki/Microservices">微服务&lt;/a>解决方案，&lt;a href="https://github.com/spring-projects/spring-cloud/wiki/Spring-Cloud-Angel-Release-Notes/6e0e1ba3d510d4a30b95c1468007b22f2427fa25">自2016年发布&lt;/a>起就被众多开发者看好。Java作为广为流行的服务端编程语言，&lt;a href="https://spring.io/projects/spring-cloud">Spring Cloud&lt;/a>也就越来越多的被用于微服务开发。&lt;/p>
&lt;p>&lt;a href="https://spring.io/projects/spring-cloud">Spring Cloud&lt;/a>集成了&lt;a href="https://netflix.github.io/">Netflix OSS&lt;/a>开源项目实现了很多功能(或作为实现之一)，包括服务治理、网关路由、客户端负载均衡、服务间调用、断路器等。&lt;a href="https://spring.io/projects/spring-cloud-netflix">Spring Cloud Netflix&lt;/a>将很多生产级别微服务能力开箱即用的带到了Spring Cloud架构下的微服务中，帮助开发者快速的构建满足&lt;a href="https://12factor.net/">12要素&lt;/a>的应用。&lt;/p>
&lt;p>在去年底发布的&lt;a href="https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now#spring-cloud-netflix-projects-entering-maintenance-mode">Spring Cloud Greenwich版本&lt;/a>中宣布&lt;a href="https://spring.io/projects/spring-cloud-netflix">Spring Cloud Netflix&lt;/a>中重要的组件&lt;a href="https://github.com/Netflix/Hystrix#hystrix-status">Hystrix&lt;/a>、&lt;a href="https://github.com/Netflix/ribbon#project-status-on-maintenance">Ribbon&lt;/a>、&lt;code>Zuul 1&lt;/code>等由于上游开源项目进入维护状态，对应的Spring Cloud Netflix项目也进入到维护状态。这些项目将&lt;strong>不再适合&lt;/strong>用于长期维护的产品中！&lt;/p>
&lt;p>同时随着近年云计算的发展，特别是&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>成为容器编排平台的事实标准，加上&lt;a href="https://www.nginx.com/blog/what-is-a-service-mesh/">Service Mesh(服务网格)&lt;/a>对微服务的服务治理和流量控制，为&lt;a href="https://www.redhat.com/en/topics/cloud-native-apps">云原生应用&lt;/a>提供了更为现代、平台无关的解决方案。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/spring-cloud-or-cloud-native/">Read More&lt;/a>&lt;/p></description></item><item><title>为Kubernetes中任意应用添加基于oauth2的认证保护 (下)</title><link>https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part2/</link><pubDate>Mon, 08 Apr 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part2/</guid><description>
&lt;p>本文是&lt;a href="https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part1/">为Kubernetes中任意应用添加基于oauth2的认证保护&lt;/a>的下篇，将图文详解如何使用基于&lt;a href="https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6">钉钉认证&lt;/a>的&lt;a href="https://github.com/bitly/oauth2_proxy">oauth2 proxy&lt;/a>为自身本没有认证授权功能的Web站点实现认证及授权。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part2/">Read More&lt;/a>&lt;/p></description></item><item><title>基于函数计算的钉钉回调函数接口</title><link>https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/</link><pubDate>Tue, 02 Apr 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/</guid><description>
&lt;p>由于企业内部管理的需要，用到了&lt;a href="https://open-doc.dingtalk.com/microapp/serverapi2/lo5n6i">钉钉的业务事件回调&lt;/a>能力，正好将这个轻量级的接口使用&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-computing-101/">无服务器技术&lt;/a>来实现部署，以应对流量无规律下的动态扩展伸缩、按需使用、按量计费等需求。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-dingtalk-callback/">Read More&lt;/a>&lt;/p></description></item><item><title>无服务器计算101</title><link>https://kane.mx/posts/effective-cloud-computing/serverless-computing-101/</link><pubDate>Mon, 01 Apr 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/serverless-computing-101/</guid><description>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Serverless_computing">Serverless Computing(无服务器计算)&lt;/a>是目前最被看好的云端计算执行模型。其最大的好处是提供分布式弹性可伸缩的计算执行环境，仅为实际使用资源付费，并且将应用维护者从常规的运维事务中解放出来，更利于专注到具体的业务上。&lt;/p>
&lt;p>在主流的应用部署方式下，无论是使用&lt;a href="https://aws.amazon.com/cn/ec2">云主机&lt;/a>还是&lt;a href="https://kane.mx/posts/effective-cloud-computing/using-kubernetes-on-cloud/">Kubernetes&lt;/a>作为运行环境，都会有大量运维层面的事务需要考虑和处理，并且应用程序需要按照分布式程序的设计准则来应对应用的水平伸缩。同时随着云计算服务的发展和完善，云计算厂商提供了越来越多的基础服务，例如API网关、对象存储、消息队列、日志、监控等服务，函数计算可以完美的同其他云服务集成，帮助用户快速实现出生产级别的弹性可伸缩的应用。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/serverless-computing-101/">Read More&lt;/a>&lt;/p></description></item><item><title>为Kubernetes中任意应用添加基于oauth2的认证保护 (上)</title><link>https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part1/</link><pubDate>Sun, 03 Feb 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part1/</guid><description>
&lt;p>企业随着业务的发展，必然会部署各种各样的IT系统。出于安全性的考虑，一些系统仅可企业内部使用，甚至仅开放给企业部分部门员工使用。&lt;/p>
&lt;p>这些IT系统大致可分为两类，&lt;/p>
&lt;ol>
&lt;li>系统本身不支持任何认证机制，例如资讯或文档类系统。需要增加认证保护，能够限制非企业员工访问即可。系统运维通常的做法是，为站点设置&lt;a href="https://en.wikipedia.org/wiki/Basic_access_authentication">HTTP Basic认证&lt;/a>保护。由于&lt;a href="https://en.wikipedia.org/wiki/Basic_access_authentication">HTTP Basic认证&lt;/a>是通过预设的用户、密码认证，认证信息比较容易泄露。即使定期更换密码，但需要额外的机制通知用户密码的变更，用户体验也不好。&lt;/li>
&lt;li>系统自身支持认证，甚至支持多种认证机制。比如最常用的开源CI/CD工具，&lt;a href="https://jenkins.io/">Jenkins&lt;/a>内置支持本地数据库认证、通过&lt;a href="https://plugins.jenkins.io/">插件&lt;/a>支持多种第三方系统集成认证。如果大量的IT系统都有一套独立的用户管理，随着企业的员工的变更，用户的增删等操作对系统管理员来说是不小的工作量。同时，也很容易由于人为疏忽，造成资产、数据的安全隐患。&lt;/li>
&lt;/ol>
&lt;p>假设企业自身已经有了一套OA系统包含员工、组织结构管理，例如，国内目前最为普及流行的&lt;a href="https://www.dingtalk.com/">钉钉&lt;/a>或&lt;a href="https://work.weixin.qq.com/">企业微信&lt;/a>。我们完全可以提供一套基于&lt;a href="https://oauth.net/2/">oauth 2.0协议&lt;/a>的认证方式，让以上两类IT系统使用企业已有的OA系统(&lt;a href="https://www.dingtalk.com/">钉钉&lt;/a>或&lt;a href="https://work.weixin.qq.com/">企业微信&lt;/a>)来实现登录认证。做到这一点后，企业无论有多少IT系统都不再需要额外管理用户的成本，并且也避免了数据安全隐患。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/oauth2-proxy-on-kubernetes/part1/">Read More&lt;/a>&lt;/p></description></item><item><title>IAM最佳实践</title><link>https://kane.mx/posts/effective-cloud-computing/iam-best-practice/</link><pubDate>Fri, 01 Feb 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/iam-best-practice/</guid><description>
&lt;p>企业使用公有云服务的第一件事情就是创建云帐号，有了帐号之后如何让企业员工安全合规的使用云帐号下的各种资源是开启云之旅后的第一个考验。&lt;/p>
&lt;p>云计算厂商针对企业上云后面临的第一个需求已经推出了完善的解决方案--&lt;a href="https://en.wikipedia.org/wiki/Identity_management">Identity and Access Management&lt;/a>。&lt;a href="https://en.wikipedia.org/wiki/Identity_management">IAM&lt;/a>可以帮助云帐号安全地控制对云计算服务资源的访问。企业可以使用IAM控制对哪个用户进行身份验证 (登录) 和授权 (具有权限) 以使用资源。&lt;/p>
&lt;p>云厂商是否提供完善的IAM服务可以作为整体产品解决方案是否成熟的一个衡量指标，比如AWS的&lt;a href="https://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/introduction.html">IAM&lt;/a>和阿里云的&lt;a href="https://help.aliyun.com/document_detail/28627.html">访问控制&lt;/a>都是较为成熟完善的产品。国内某个以AI能力为卖点的云厂商，在IAM产品方面几乎为零，很难相信对安全合规有需求的企业会完整使用他的云产品作为解决方案。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/iam-best-practice/">Read More&lt;/a>&lt;/p></description></item><item><title>不要自建Kubernetes</title><link>https://kane.mx/posts/effective-cloud-computing/using-kubernetes-on-cloud/</link><pubDate>Tue, 22 Jan 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/using-kubernetes-on-cloud/</guid><description>
&lt;p>这是“如何高效使用云服务”系列文章的首篇分享。可能有朋友好奇为什么不是从云计算最基础的服务--计算资源&lt;a href="https://cn.aliyun.com/product/ecs">ECS&lt;/a>/&lt;a href="https://aws.amazon.com/cn/ec2/">EC2&lt;/a>讲起呢？在&lt;a href="https://pivotal.io/cloud-native">Cloud Native&lt;/a>已经被越来越接受的今天，基于&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>部署、编排应用的方式已经是业界的事实标准。无论是互联网巨头，传统500强企业，还是创业团队都在使用或规划使用&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>作为应用程序的自动化部署、可扩展管理平台。在云计算平台，虚拟机越来越不需要单独的管理，在绝大多数的业务场景下，它们只是作为容器集群所管理的计算资源。甚至虚拟机的创建到销毁整个生命周期管理都可以由&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>根据集群的负载来自动完成。&lt;/p>
&lt;p>所有主流的云计算厂商都在解决方案中力推托管的&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>，&lt;a href="https://aws.amazon.com/cn/">AWS&lt;/a>的&lt;a href="https://aws.amazon.com/eks">EKS&lt;/a>，&lt;a href="https://azure.microsoft.com/en-us/">Azure&lt;/a>上的&lt;a href="https://azure.microsoft.com/en-us/services/kubernetes-service/">AKS&lt;/a>，当然少不了Google家&lt;a href="https://cloud.google.com/">GCP&lt;/a>上的&lt;a href="https://cloud.google.com/kubernetes-engine/">Kubernetes Engine&lt;/a>。国内&lt;a href="https://www.aliyun.com/product/kubernetes">阿里云&lt;/a>，&lt;a href="https://cloud.tencent.com/product/tke">腾讯云&lt;/a>等每一个公有云玩家也都基于开源&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>推出了托管服务。如果一家云计算厂商在提供托管&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a>这一服务上没跟上业界的步伐，将来极大可能被淘汰出这个市场。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/using-kubernetes-on-cloud/">Read More&lt;/a>&lt;/p></description></item><item><title>真的会用云服务吗？</title><link>https://kane.mx/posts/effective-cloud-computing/preface/</link><pubDate>Mon, 07 Jan 2019 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/effective-cloud-computing/preface/</guid><description>
&lt;p>这是“如何高效使用云服务”系列文章的引子。该系列将讲述如何利用各种公有云服务来安全合规、高质量、快速、低成本的打造产品/系统，帮助企业（特别是中小微创业团队）在人少，钱缺的情况下做到最高效率。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/effective-cloud-computing/preface/">Read More&lt;/a>&lt;/p></description></item><item><title>2018北京ArchSummit回顾</title><link>https://kane.mx/posts/2018/2018-12-13-bj-archsummit-review/</link><pubDate>Thu, 13 Dec 2018 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2018/2018-12-13-bj-archsummit-review/</guid><description>
&lt;p>上周参加了&lt;a href="https://bj2018.archsummit.com">ArchSummit(全球架构师峰会)&lt;/a>，在这里记录下部分参加的主题以及个人感受。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2018/2018-12-13-bj-archsummit-review/">Read More&lt;/a>&lt;/p></description></item><item><title>如何修复Jenkins CI无法读取存在的任务配置</title><link>https://kane.mx/posts/2016/how-to-fix-jenkins-fail-to-load-job-config/</link><pubDate>Wed, 12 Oct 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/how-to-fix-jenkins-fail-to-load-job-config/</guid><description>
&lt;p>&lt;a href="https://vme360.com">V秘&lt;/a>开发团队一直使用着&lt;a href="https://jenkins.io/">Jenkins CI&lt;/a>来持续集成&lt;a href="https://vme360.com">V秘&lt;/a>服务的新功能和各种改进。近日，&lt;a href="https://jenkins.io/">Jenkins CI&lt;/a>在重启之后，很多已有任务的配置无法被&lt;a href="https://jenkins.io/">Jenkins CI&lt;/a>完整的加载，导致很多功能无法使用。导致我们整个网站的各种服务无法被升级更新了:-(&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/how-to-fix-jenkins-fail-to-load-job-config/">Read More&lt;/a>&lt;/p></description></item><item><title>MongoDB中如何找出慢查询</title><link>https://kane.mx/posts/2016/how-to-find-slow-queries-in-mongodb/</link><pubDate>Thu, 29 Sep 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/how-to-find-slow-queries-in-mongodb/</guid><description>
&lt;p>&lt;a href="https://www.mongodb.com/">MongoDB&lt;/a>是目前最为流行的&lt;a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL&lt;/a>数据库之一。&lt;a href="https://vme360.com">V秘&lt;/a>的后台数据就是保存在&lt;a href="https://www.mongodb.com/">MongoDB&lt;/a>中的哦;)&lt;/p>
&lt;p>尽管&lt;a href="https://www.mongodb.com/">MongoDB&lt;/a>的性能为业界称道，但任何数据库系统使用中都存在着慢查询的问题。慢查询的性能问题，可能是由于使用非最优的查询语句，不正确的索引或其他配置原因导致的。但开发人员或数据库维护人员首先要找出这些低效的查询，才能做出对应的查询优化。&lt;/p>
&lt;!-- more -->
&lt;p>在&lt;a href="https://www.mongodb.com/">MongoDB&lt;/a>中实现慢查询的profile是非常容易，因为&lt;a href="https://www.mongodb.com/">MongoDB&lt;/a>内置了&lt;a href="https://docs.mongodb.com/manual/reference/method/db.setProfilingLevel/">profile开关&lt;/a>来记录执行时间触发了profile条件的查询。&lt;/p>
&lt;p>参照&lt;a href="https://docs.mongodb.com/manual/reference/method/db.setProfilingLevel/">db.setProfileLevel()&lt;/a>的文档，通过以下命令就可以记录执行时长超过&lt;strong>300ms&lt;/strong>的查询。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="nx">db&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setProfilingLevel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">300&lt;/span>&lt;span class="p">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>当慢查询被重现后，可以通过查找&lt;code>system.profile&lt;/code> collection来查看执行时长超过&lt;strong>300ms&lt;/strong>的查询。&lt;/p>
&lt;p>被profiler记录下来慢查询record看起来如下，&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/how-to-find-slow-queries-in-mongodb/">Read More&lt;/a>&lt;/p></description></item><item><title>Docker Swarm mode(v1.12.x)的一些使用限制</title><link>https://kane.mx/posts/2016/the-limitations-docker-swarm-mode-v1.12/</link><pubDate>Tue, 20 Sep 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/the-limitations-docker-swarm-mode-v1.12/</guid><description>
&lt;p>&lt;a href="https://docs.docker.com/engine/swarm/">Swarm mode&lt;/a>在&lt;a href="https://www.docker.com">Docker&lt;/a> v1.12中正式发布，&lt;a href="https://docs.docker.com/engine/swarm/">Swarm mode&lt;/a>带来了诸如Docker集群，容器编排，多主机网络等激动人心的特性。&lt;a href="https://vme360.com">V秘&lt;/a>团队也尝试着将各种后台服务部署到&lt;a href="https://docs.docker.com/engine/swarm/">Docker Swarm Cluster&lt;/a>获取更好的弹性计算能力。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/the-limitations-docker-swarm-mode-v1.12/">Read More&lt;/a>&lt;/p></description></item><item><title>创建于Docker Swarm的服务无法在Ubuntu 14.04 LTS中运行</title><link>https://kane.mx/posts/2016/docker-swarm-mode-in-ubuntu-1404/</link><pubDate>Tue, 13 Sep 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/docker-swarm-mode-in-ubuntu-1404/</guid><description>
&lt;p>&lt;a href="https://vme360.com">V秘&lt;/a>团队一直致力于用技术改善产品。&lt;a href="https://vme360.com">V秘&lt;/a>后台的各种服务一直是通过完善的Devops流程自动部署到&lt;a href="https://www.docker.com">Docker&lt;/a>容器集群。随着&lt;a href="https://docs.docker.com/engine/swarm/">Swarm mode&lt;/a>在&lt;a href="https://www.docker.com">Docker&lt;/a> v1.12中正式发布，&lt;a href="https://docs.docker.com/engine/swarm/">Swarm mode&lt;/a>带来了诸如Docker集群，多主机网络等激动人心的特性。我们也在尝试将&lt;a href="https://vme360.com">V秘&lt;/a>服务部署到&lt;a href="https://docs.docker.com/engine/swarm/">Docker Swarm Cluster&lt;/a>获取更好的弹性计算能力。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/docker-swarm-mode-in-ubuntu-1404/">Read More&lt;/a>&lt;/p></description></item><item><title>基于Angularjs单页面应用的SEO优化</title><link>https://kane.mx/posts/2016/seo-optimization-for-angularajs-based-app/</link><pubDate>Thu, 19 May 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/seo-optimization-for-angularajs-based-app/</guid><description>
&lt;p>在之前的&lt;a href="https://kane.mx/posts/2016/single-page-app-meets-weixin-pay/">文章&lt;/a>我曾提到基于&lt;a href="https://angularjs.org/">Angularjs&lt;/a>的单页面应用在用户体验上的种种好处。然而任何事情都不是完美的，&lt;a href="https://angularjs.org/">Angular&lt;/a>和类似的框架通过应用内做页面路由的实现给SEO（也俗称搜索引擎优化）带来了不少麻烦。&lt;/p>
&lt;p>首先，我们来看看页面内路由是如何实现的。默认&lt;a href="https://angularjs.org/">Angularjs&lt;/a>生成的页面uri类型如下，&lt;/p>
&lt;p>&lt;code>http://mydomain.com/#/app/page1&lt;/code>&lt;/p>
&lt;p>浏览器请求上面这个uri的时候，实际发送给服务器的请求地址是&lt;strong>&lt;a href="http://mydomain.com/">http://mydomain.com/&lt;/a>&lt;/strong>, web服务器会将默认的页面响应给浏览器，比如&lt;em>index.html&lt;/em>或&lt;em>index.php&lt;/em>等。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/seo-optimization-for-angularajs-based-app/">Read More&lt;/a>&lt;/p></description></item><item><title>Spring框架下的分布式session管理</title><link>https://kane.mx/posts/2016/clustered-session-under-spring-framework/</link><pubDate>Sat, 07 May 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/clustered-session-under-spring-framework/</guid><description>
&lt;p>在微服务和容器等技术的帮助下，Web应用可以较为容易的进行水平扩展，来部署更多的应用实例来提升请求处理数QPS。当Web服务有状态的时候，如何在集群下管理用户session成为新的待解决问题。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/clustered-session-under-spring-framework/">Read More&lt;/a>&lt;/p></description></item><item><title>V秘是如何构建的</title><link>https://kane.mx/posts/2016/how-we-build-videome/</link><pubDate>Thu, 07 Apr 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/how-we-build-videome/</guid><description>
&lt;p>春天来了，&lt;a href="https://vme360.com">V秘&lt;/a>大家庭也新增了两位10后的传人。新爸爸经过一番忙乱后，希望在这里与大家分享&lt;a href="https://vme360.com">V秘&lt;/a>的架构，共同探讨如何快速的构建高可用，高性能的Web服务。&lt;/p>
&lt;p>&lt;a href="https://vme360.com">V秘&lt;/a>致力于提供最好的在线视频制作云平台。让用户随时随地零门槛的快速制作出高质量高清晰度的视频，来纪念记录生活中有意义的时刻，同时将这份快乐传递给更多的家人朋友一起分享。&lt;/p>
&lt;p>然而要可靠的可扩展的实现这样看似简单的需求，其背后确由众多知名开源技术，可靠的云服务，不间歇的监控运维来实现和保证的。&lt;/p>
&lt;!-- more -->
&lt;p>&lt;a href="https://vme360.com">V秘&lt;/a>架构的基本目标就是要实现，&lt;/p>
&lt;ul>
&lt;li>服务的高扩展性。有有效可靠的方法支撑数万并发到数十万，百万及更多的并发请求。&lt;/li>
&lt;li>服务的高可用性。各种服务都是多实例的集群，某些服务故障后，集群中的其他实例仍然能够提供服务。&lt;/li>
&lt;li>服务的自动化构建。从代码到服务部署上线是一套自动化的流程，越少的人工介入保证了服务的可用性。&lt;/li>
&lt;li>系统的实时监控。7x24小时的监控保证服务的可用性，当监控到数据异常或服务停止运行能及时告警引入人工运维团队。&lt;/li>
&lt;/ul>
&lt;p>更多细节请参阅下面的&lt;a href="http://www.slideshare.net/zxkane/how-we-build-vme">slides&lt;/a>,&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/how-we-build-videome/">Read More&lt;/a>&lt;/p></description></item><item><title>说一说阿里云ossfs</title><link>https://kane.mx/posts/2016/aliyun-ossfs-sucks/</link><pubDate>Fri, 26 Feb 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/aliyun-ossfs-sucks/</guid><description>
&lt;p>阿里云提供的对象或者文件存储叫&lt;a href="https://www.aliyun.com/product/oss">OSS&lt;/a>，为应用程序提供了海量存储，按需付费等服务。应用程序则需要通过&lt;a href="https://www.aliyun.com/product/oss">Aliyun OSS&lt;/a>的各语言SDK才能操作（读，写，遍历等）OSS中的文件。&lt;/p>
&lt;p>对运维人员来说，做一些数据维护工作的时候，通过SDK操作&lt;a href="https://www.aliyun.com/product/oss">OSS&lt;/a>中的文件就会比较麻烦。在linux/unix环境下，通常有一些工具把远程文件系统或云盘挂载为本地文件。在网络状况比较好的情况下，操作远程文件就像操作本地文件一样。例如，把&lt;a href="https://github.com/s3fs-fuse/s3fs-fuse">Amazon S3&lt;/a>，&lt;a href="https://github.com/joe42/CloudFusion">Dropbox云盘&lt;/a>，&lt;a href="https://github.com/libfuse/sshfs">可通过ssh登录的远程服务器上的磁盘&lt;/a>挂载为本地文件系统。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/aliyun-ossfs-sucks/">Read More&lt;/a>&lt;/p></description></item><item><title>如何使用微信公众平台的临时素材</title><link>https://kane.mx/posts/2016/weixin-temporary-materials/</link><pubDate>Wed, 27 Jan 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/weixin-temporary-materials/</guid><description>
&lt;p>微信给公众平台提供了&lt;a href="http://mp.weixin.qq.com/wiki/15/2d353966323806a202cd2deaafe8e557.html">素材管理&lt;/a>的接口，通过这一系列接口可以上传，接收以及管理图片，视频等多媒体文件。其中又分为&lt;strong>临时&lt;/strong>和&lt;strong>永久&lt;/strong>两种类型。永久素材有总量的限制，临时素材微信服务器只给保存3天。&lt;/p>
&lt;p>最近&lt;a href="https://vme360.com">V秘&lt;/a>刚好有个同微信用户互动的场景，为用户美化微信拍摄的小视频。&lt;a href="https://vme360.com">V秘&lt;/a>后台服务器收到用户发送过来小视频（微信将其认做临时素材），将其美化处理后，再将美化的视频上传为临时素材，最终美化后的视频作为视频类型的客服消息被推送给用户。整个流程很简洁，用户发送小视频后，就坐等观看美化后的小视频了。&lt;/p>
&lt;p>然而最终经过V秘开发团队的实践及测试，得出的结论是，&lt;/p>
&lt;!-- more -->
&lt;p>##&lt;strong>微信公众平台的临时素材不能用！绝对的鸡肋！&lt;/strong>&lt;/p>
&lt;p>公众平台上传素材的API以及使用已有素材发送视频消息API都很健壮。但问题出在了微信后台资源的服务上面。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/weixin-temporary-materials/">Read More&lt;/a>&lt;/p></description></item><item><title>单页面应用(single page application)中使用微信支付</title><link>https://kane.mx/posts/2016/single-page-app-meets-weixin-pay/</link><pubDate>Sun, 24 Jan 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/single-page-app-meets-weixin-pay/</guid><description>
&lt;p>随着&lt;strong>AngularJS&lt;/strong>等前端MVC框架的流行，AJAX的异步请求数据结合H5的push state等特性，极大的改善了网站的用户体验和页面加载性能。这类网站应用通常只有一个入口页面，通过应用内路由到不同的页面，所以俗称单页面(signle page application)应用。页面&lt;strong>URL&lt;/strong>看起来如下，&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/single-page-app-meets-weixin-pay/">Read More&lt;/a>&lt;/p></description></item><item><title>文件系统的Inode耗尽，会导致Docker编译镜像出现'No space left on device'错误</title><link>https://kane.mx/posts/2016/docker-build-no-space-left-caused-by-inode-exhausted/</link><pubDate>Thu, 21 Jan 2016 00:00:00 +0000</pubDate><guid>https://kane.mx/posts/2016/docker-build-no-space-left-caused-by-inode-exhausted/</guid><description>
&lt;p>最近在提交前端代码后，前端代码的自动发布老是失败。失败的原因多是编译Docker镜像时在执行&lt;code>COPY&lt;/code>语句拷贝文件到镜像文件系统时，扔出了'No space left on device'这个错误。这个错误根据描述非常好理解，就是docker文件系统所在磁盘没有了空间。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/2016/docker-build-no-space-left-caused-by-inode-exhausted/">Read More&lt;/a>&lt;/p></description></item><item><title>Daemon hell in Jenkins</title><link>https://kane.mx/posts/archive/blogspot/daemon-hell-in-jenkins/</link><pubDate>Tue, 21 Jul 2015 09:32:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/daemon-hell-in-jenkins/</guid><description>
&lt;p>Recently I wrote a Linux like &lt;a href="https://gist.github.com/zxkane/b55033bd519334d57c13">initd script&lt;/a> to start/stop my web application.&lt;/p>
&lt;p>The script works well when running it in shell of linux. The web application will run in background by daemon.&lt;/p>
&lt;p>However I found both daemon and web application(java) exited immediately if I started the script in Jenkins as a shell step of build process.&lt;/p>
&lt;p>I put below simple script in 'Execute shell' block,&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">daemon --name&lt;span class="o">=&lt;/span>test-daemon -- sleep 200sleep &lt;span class="m">60&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>The process 'daemon' and 'sleep 200' should exit after 200 seconds the 'sleep' exits. The jenkins job will be finished in 60 secs.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/daemon-hell-in-jenkins/">Read More&lt;/a>&lt;/p></description></item><item><title>The symptoms of Java broken in Mac OSX 10.10 and fix solution</title><link>https://kane.mx/posts/archive/blogspot/the-symptoms-of-java-broken-in-mac-osx/</link><pubDate>Mon, 13 Jul 2015 19:11:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/the-symptoms-of-java-broken-in-mac-osx/</guid><description>
&lt;p>After uninstalling some applications from my Mac OSX, I found the applications that depends on JRE totally does not work. I noticed below symptoms,&lt;/p>
&lt;ol>
&lt;li>Eclipse Mars can not be launched, even though I specified the launching vm to another one(`java -version` still work). The SWT native library failed to resolve the dependencies to '/System/Library/Frameworks/JavaVM.framework/Versions/A/JavaVM' which does not exists.&lt;/li>
&lt;li>I tried to reinstall Oracle 1.8.0_u45 via both brew and dmg image downloaded from Oracle website, both ways were failed as well.&lt;/li>
&lt;li>The Mac pkg Installer can not be started due to dylib broken. It means I can't install any pkg via GUI. The command line(such as &lt;code>sudo installer -verboseR -target / -pkg /Volumes/OS\ X\ 10.10.4\ Update\ Combo/OSXUpdCombo10.10.4.pkg&lt;/code>) still works.&lt;/li>
&lt;/ol>
&lt;p>Finally I realized the problem was caused by I uninstalled the out of date Apple Java 6. Looks like all of above failures are required the system built-in Java. It really does not make sense the Oracle 1.8 installer script to depend on the out of date Java.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/the-symptoms-of-java-broken-in-mac-osx/">Read More&lt;/a>&lt;/p></description></item><item><title>Run groovy script via Jenkins CLI</title><link>https://kane.mx/posts/archive/blogspot/run-groovy-script-via-jenkins-cli/</link><pubDate>Mon, 13 May 2013 13:44:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/run-groovy-script-via-jenkins-cli/</guid><description>
&lt;p>Jenkins supports &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Jenkins&amp;#43;SSH">ssh authentication&lt;/a> in CLI.&lt;/p>
&lt;p>Below is a command to verify that I am authenticated:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">java -jar jenkins-cli.jar -s http://myserver/jenkins who-am-i
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">    Authenticated as: myuser
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">    Authorities:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">        authenticated&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>However you still would meet permission error when running groovy script in CLI.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">java -jar jenkins-cli.jar -s http://myserver/jenkins groovysh &lt;span class="s1">&amp;#39;jenkins.model.Jenkins.instance.pluginManager.plugins.each { println(&amp;#34;${it.longName} - ${it.version}&amp;#34;) };&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">Exception in thread &lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span> java.lang.reflect.UndeclaredThrowableException
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">at &lt;span class="nv">$Proxy2&lt;/span>.main&lt;span class="o">(&lt;/span>Unknown Source&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">at hudson.cli.CLI.execute&lt;span class="o">(&lt;/span>CLI.java:271&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">at hudson.cli.CLI._main&lt;span class="o">(&lt;/span>CLI.java:417&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">at hudson.cli.CLI.main&lt;span class="o">(&lt;/span>CLI.java:322&lt;span class="o">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>It's a bug of Jenkins. &lt;strong>The workaround is create a groovy script, then run that script via Jenkins CLI&lt;/strong>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/run-groovy-script-via-jenkins-cli/">Read More&lt;/a>&lt;/p></description></item><item><title>Solr boost examples</title><link>https://kane.mx/posts/archive/blogspot/solr-boost-examples/</link><pubDate>Sat, 11 May 2013 13:16:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/solr-boost-examples/</guid><description>
&lt;p>The index has a field named 'create_time' that is the timestamp of document created time. The query string can boost the latest created document like below,&lt;/p>
&lt;p>{!boost b=recip(ms(NOW,create_time),3.16e-11,0.08,0.05)}name:keyword&lt;/p>
&lt;p>There is another field named 'important' that indicates whether the document is important or not. The query string can boost the document is important like below,&lt;/p>
&lt;p>q={!boost b=$importfunc}name:keyword&amp;amp;importfunc=query({!v='important:true'})&lt;/p>
&lt;p>Above query string uses a sub query in boost function.&lt;/p>
&lt;p>Finally I want to boost both above two fields, and 'important' field has higher priority. The query string looks like below,&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/solr-boost-examples/">Read More&lt;/a>&lt;/p></description></item><item><title>Django's unicdoe encode error</title><link>https://kane.mx/posts/archive/blogspot/djangos-unicdoe-encode-error/</link><pubDate>Thu, 16 Aug 2012 09:11:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/djangos-unicdoe-encode-error/</guid><description>
&lt;p>It's a common and ugly problem when using non-ascii characters in Django.&lt;/p>
&lt;p>The general solution is below,&lt;/p>
&lt;ol>
&lt;li>put &lt;strong># -&lt;em>- coding: utf-8 -&lt;/em>-&lt;/strong> at beginning of every python source files that are using utf-8 characters&lt;/li>
&lt;li>declare every string variable as unicode, such as &lt;strong>str_var = u'中文字符'&lt;/strong>&lt;/li>
&lt;li>add &lt;a href="https://docs.djangoproject.com/en/1.4/ref/models/instances/#django.db.models.Model.__unicode__">a __unicode__&lt;/a> method in your model classes&lt;/li>
&lt;li>if you are running server on apache/mod_wsgi or ngnix, you need &lt;a href="https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror">configure web server to use utf-8 encoding&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/djangos-unicdoe-encode-error/">Read More&lt;/a>&lt;/p></description></item><item><title>The workaround of making Zend CE/Zend debugger work on mountain lion</title><link>https://kane.mx/posts/archive/blogspot/workaround-of-making-zend-ce-mountain-lion/</link><pubDate>Sat, 28 Jul 2012 20:49:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/workaround-of-making-zend-ce-mountain-lion/</guid><description>
&lt;p>I installed both Zend CE and zend debugger of Eclipse on my Mac. Both of them work well in Mac lion.  However they don't work any more after I upgraded my Mac to mountain lion. &lt;/p>
&lt;p>After some investigation I found some extensions of Zend PHP can't be loaded due to shared library dependency can't be found in mountain lion. The &lt;strong>xslt&lt;/strong> module of PHP depends on some system libraries(suc as /usr/local/libxslt-1.1.23/lib/libxslt.1.dylib) that have been removed by mountain lion.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/workaround-of-making-zend-ce-mountain-lion/">Read More&lt;/a>&lt;/p></description></item><item><title>Dual monitors on Ubuntu</title><link>https://kane.mx/posts/archive/blogspot/dual-monitors-on-ubuntu/</link><pubDate>Mon, 19 Mar 2012 20:04:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/dual-monitors-on-ubuntu/</guid><description>
&lt;p>I had two monitors for my workstation. One is 22' and the another is 17'. I used the small one as a extend desktop.&lt;/p>
&lt;p>Today I get a another 23' monitor to replace the small one. However the resolution of the 23' monitor can't be changed after pluging it in. It always used the resolution matching the 17' one.&lt;/p>
&lt;p>Both 'Setting - Display' and 'AMD Catalyst control' can't adjust it as higher resolution.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/dual-monitors-on-ubuntu/">Read More&lt;/a>&lt;/p></description></item><item><title>Embedding an HTTP server in Equinox</title><link>https://kane.mx/posts/archive/blogspot/embedding-http-server-in-equinox/</link><pubDate>Mon, 05 Mar 2012 19:25:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/embedding-http-server-in-equinox/</guid><description>
&lt;p>I want to create a test server for my application. Using embedding Http server in equinox is my first option.&lt;/p>
&lt;p>I had experience using simple http service implementation of equinox, however I want to play with Jetty this time.&lt;/p>
&lt;p>Following &lt;a href="http://www.eclipse.org/equinox/server/http_in_equinox.php">the guide&lt;/a> of Equinox server, I can't running a Jetty server with my servlet in Eclipse Indigo. Obviously &lt;a href="http://www.eclipse.org/equinox/server/http_in_equinox.php">the guide&lt;/a> is out of date.&lt;/p>
&lt;p>After tuning it, I found below bundles are minimum collection to run Jetty inside OSGi runtime.&lt;br>
&lt;script src="https://gist.github.com/zxkane/1977922.js?file=embedded-jetty-osgi">&lt;/script>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/embedding-http-server-in-equinox/">Read More&lt;/a>&lt;/p></description></item><item><title>Acess Intranet without VPN</title><link>https://kane.mx/posts/archive/blogspot/acess-intranet-without-vpn/</link><pubDate>Fri, 17 Feb 2012 17:47:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/acess-intranet-without-vpn/</guid><description>
&lt;p>Sometimes I need access the Intranet of company, however I don't like to create VPN connection. The connection is slow, waste time to create the connection and have to change password due to security policy.&lt;/p>
&lt;p>My workstation is Linux, which has a lot of utility tools to help me access Intranet at home without VPN.&lt;/p>
&lt;p>Firstly I set up a ssh server on my personal computer. It's quite easy if you are using Linux, for Windows I installed &lt;a href="https://www.itefix.no/i2/copssh">Copssh&lt;/a>.&lt;br>
Then register a free domain name and configure it in my router. And let router forward port &lt;code>22&lt;/code>(or any port you wan to use) to my personal computer.&lt;br>
In my working Linux machine, create a ssh tunnel to my personal computer. Must use the &lt;a href="https://kane.mx/posts/archive/blogspot/ssh-key/">public/private key for authenticating&lt;/a>. For example,&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/acess-intranet-without-vpn/">Read More&lt;/a>&lt;/p></description></item><item><title>How to reuse the existing OpenID accounts after the host name of Gerrit server is changed</title><link>https://kane.mx/posts/archive/blogspot/how-to-reuse-existing-openid-accounts/</link><pubDate>Wed, 15 Feb 2012 11:36:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-reuse-existing-openid-accounts/</guid><description>
&lt;p>An internal Gerrit server was moved, so the hostname of server is changed. However we are using OpenID for user control, the OpenID provider(such as Google account) will generate a new token for the new server(hostname changing will impact the identity token of Google account) when we login Gerrit with same OpenID account. Gerrit will create a new internal account by default even though my OpenID account has existed in the system and has a lot of activities.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-reuse-existing-openid-accounts/">Read More&lt;/a>&lt;/p></description></item><item><title>JRE/JDK's certificate issue and solution</title><link>https://kane.mx/posts/archive/blogspot/jrejdks-certificate-issue-and-solution/</link><pubDate>Thu, 24 Nov 2011 15:58:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/jrejdks-certificate-issue-and-solution/</guid><description>
&lt;p>The problem came from I tried to set up send mail server(SMTP) for my Gerrit server. My Gerrit server is using OpenID for user authorization, so I registered a new email account to send notification from Gerrit.&lt;/p>
&lt;p>Most of email service providers require the secure authorization when using its SMTP server to send mail. However the root CA of my email provider is not added into the default certificate of JRE. So Gerrit always failed to send email due to ssl verification exception.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/jrejdks-certificate-issue-and-solution/">Read More&lt;/a>&lt;/p></description></item><item><title>The tips of Maven/Tycho building crossplatform RCP and repository</title><link>https://kane.mx/posts/archive/blogspot/tips-of-maventycho-building/</link><pubDate>Tue, 08 Nov 2011 16:16:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/tips-of-maventycho-building/</guid><description>
&lt;p>I successfully converted our product build from PDE build to Maven/Tycho. Something is worth to be documented here.&lt;/p>
&lt;p>There are several examples and posts to demonstrate how using Tycho building your Eclipse plug-ins, features, applications and products. The most helpful example is the &lt;a href="http://git.eclipse.org/c/tycho/org.eclipse.tycho.git/tree/tycho-demo">demo&lt;/a> of Tycho project.&lt;/p>
&lt;p>Below are some traps I met when building my project by Tycho,&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>product build&lt;/strong>&lt;br>
Our product is based on plug-ins, however we added the '&lt;strong>featurelist&lt;/strong>' in build.properties of PDE build to include some root binary for the product. However Tycho doesn't support this type of build, we create some features as the placeholder of plug-ins. Then change the product as features based. You have to manually remove the &lt;strong>plugins&lt;/strong> tag in .product definition file, otherwise Tycho will fail on strange error if the .produce has both &lt;strong>features&lt;/strong> and &lt;strong>plugins&lt;/strong> tag. Then configure the director plugin as not installing features.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/tips-of-maventycho-building/">Read More&lt;/a>&lt;/p></description></item><item><title>Migration Clearcase to Git -- part 2</title><link>https://kane.mx/posts/archive/blogspot/migration-clearcase-to-git-part-2/</link><pubDate>Tue, 25 Oct 2011 19:45:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/migration-clearcase-to-git-part-2/</guid><description>
&lt;p>Several days ago I had a post to record the unsuccessful experience to migrate source code from Clearcase to Git.&lt;/p>
&lt;p>We have a new way after doing some brain storms. This way still is not a perfect solution, but it's much better than previous trial.&lt;/p>
&lt;ol>
&lt;li>Use &lt;strong>clearexport_ccase&lt;/strong> to export the source folder to intermittent data. See &lt;a href="http://publib.boulder.ibm.com/infocenter/cchelp/v7r0m1/index.jsp?topic=/com.ibm.rational.clearcase.cc_ref.doc/topics/clearexport_ccase.htm">documentation&lt;/a> of Clearcase admin.&lt;/li>
&lt;li>Create a temporary vob for importing the data later. See &lt;a href="http://publib.boulder.ibm.com/infocenter/cchelp/v7r0m1/index.jsp?topic=/com.ibm.rational.clearcase.tutorial.doc/a_cr_storagecomp_fcc_ux.htm">example&lt;/a>.&lt;/li>
&lt;li>Import the data into temporary vob. See &lt;a href="http://www.philforhumanity.com/ClearCase_Support_38.html">example&lt;/a>.&lt;/li>
&lt;li>Repeat step 1 to 3 for importing all necessary data into temporary vob.&lt;/li>
&lt;li>Use the SVN Importer to import the temporary vob as Subversion repository.&lt;/li>
&lt;li>Last steps refer to a documentation of &lt;a href="http://www.winklerweb.net/index.php/blog/4-eclipse/16-migrating-the-cdo-svn-repository-to-git">succeeded migration case&lt;/a> of one of Eclipse project from Subversion to Git.&lt;/li>
&lt;/ol>
&lt;p>Git definitely is greatest SCM tool now. The size of Subversion repository is around 10GB, finally the Git repository is less than 700MB, which saves more than 10 times disk space. It's awesome!&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/migration-clearcase-to-git-part-2/">Read More&lt;/a>&lt;/p></description></item><item><title>Migrate Clearcase to Git</title><link>https://kane.mx/posts/archive/blogspot/migrate-clearcase-to-git/</link><pubDate>Mon, 17 Oct 2011 19:50:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/migrate-clearcase-to-git/</guid><description>
&lt;p>I tried to migrate the source code of project from Clearcase to Git repository. As far as I know there is no elegant solution for such migration. For purpose of this migration, I want to keep the history and label of files in Clearcase after migrating to Git repository.&lt;/p>
&lt;p>There are mature tools to migrate CVS/SVN repository to Git, so I tried to use Subversion as a bridge for my migration.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/migrate-clearcase-to-git/">Read More&lt;/a>&lt;/p></description></item><item><title>p2 query performance</title><link>https://kane.mx/posts/archive/blogspot/p2-query-performance/</link><pubDate>Mon, 17 Oct 2011 19:34:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/p2-query-performance/</guid><description>
&lt;p>Our p2 based on installer suffered performance issue when querying IUs from repositories. Though the repositories have a large number of IUs to be queried, but we find the performance of using QL is unacceptable in some special scenarios.&lt;/p>
&lt;p>I &lt;a href="https://docs.google.com/document/d/1wfnr2d2TF4vIYDCMmWPuYd0kQA32WiWaXTiaCoJovho/edit?pli=1">published several different methods&lt;/a> to find the expected IUs. Thomas pointed out the better expression of QL and finally helped us to find out the our repository without &lt;strong>IIndexProvider&lt;/strong> implementation.&lt;/p>
&lt;p>&lt;strong>IIndexProvider&lt;/strong> implementation of a repository is quite important to improve the performance of QL, especially use the 'traverse' clause to query something.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/p2-query-performance/">Read More&lt;/a>&lt;/p></description></item><item><title>Create an import library for building application in MinGW</title><link>https://kane.mx/posts/archive/blogspot/create-import-library-for-building/</link><pubDate>Fri, 12 Aug 2011 10:51:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/create-import-library-for-building/</guid><description>
&lt;p>Yesterday I modified an existing c++ application for Windows. And its default build environment is Makefile and MinGW.&lt;/p>
&lt;p>However I used a newly Windows API that is not included by header files of MinGW.&lt;/p>
&lt;p>First of all, I copied the constant definition from header file of Windows SDK, and defined the Windows API method as a extern C method. So it's no problem to compile the code in MinGW.&lt;/p>
&lt;p>Secondly I have to fix the link issue. Because the symbol of the Windows API also can't be found by gcc link.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/create-import-library-for-building/">Read More&lt;/a>&lt;/p></description></item><item><title>Customize PDE build</title><link>https://kane.mx/posts/archive/blogspot/customize-pde-build/</link><pubDate>Fri, 22 Jul 2011 13:59:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/customize-pde-build/</guid><description>
&lt;p>&lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_customization.htm">The documentation of PDE&lt;/a> has a chapter for this topic. Basically it's simply. Copy the template scripts what you want from &lt;em>templates/headless-build&lt;/em> folder under &lt;em>org.eclipse.pde.build&lt;/em> plug-in to your build configuration directory that is the folder has &lt;em>build.properties&lt;/em> file.&lt;/p>
&lt;p>However I found the variables listed in template '&lt;em>customAssembly.xml&lt;/em>' can't be used in the runtime. I filed bug &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346370">346370&lt;/a> against it.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/customize-pde-build/">Read More&lt;/a>&lt;/p></description></item><item><title>Using the certificate of Windows code signing to sign jars</title><link>https://kane.mx/posts/archive/blogspot/using-certificate-of-windows-code/</link><pubDate>Mon, 18 Jul 2011 21:03:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/using-certificate-of-windows-code/</guid><description>
&lt;p>I did sign the jars via reusing the existing certificate of Windows code signing several months ago. Writing it down for further reference.&lt;/p>
&lt;p>Whatever your purpose of reusing the existing Windows code certificate, I only document the way from technical perspective.&lt;/p>
&lt;p>After buying the certificate of Windows code signing from CA, you will get a .pvk file that stores both the certificate and private key. PVK file is the PKCS12 format[1], however java uses JKS format by default. So you need convert the pvk file to JKS keystore and certificate.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/using-certificate-of-windows-code/">Read More&lt;/a>&lt;/p></description></item><item><title>Unlock the locked profile if firefox/thunderbird crash</title><link>https://kane.mx/posts/archive/blogspot/unlock-locked-profile-if/</link><pubDate>Wed, 11 May 2011 13:19:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/unlock-locked-profile-if/</guid><description>
&lt;p>I met that firefox/thunderbird complained another its instance running even if no a running firefox/thunderbird process. Finally let them run again after removing the '.parentlock' file in their default profile.&lt;/p>
&lt;p>strace utility helps me a lot to find the solution.&lt;/p>
&lt;p>&lt;strong>strace -f -e file firfox&lt;/strong>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/unlock-locked-profile-if/">Read More&lt;/a>&lt;/p></description></item><item><title>Eclipse P2's import/export capability</title><link>https://kane.mx/posts/archive/blogspot/eclipse-p2s-importexport-capability/</link><pubDate>Fri, 22 Apr 2011 15:56:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/eclipse-p2s-importexport-capability/</guid><description>
&lt;p>I implemented the &lt;a href="https://kane.mx/posts/archive/blogspot/p2-replication-plug-in/">replication tool&lt;/a> at the end of 2009, then published it to &lt;a href="https://kane.mx/posts/archive/blogspot/p2-replication-tool-lives-on-eclipse/">Eclipse Marketplace&lt;/a> in May 2010. However it's not pervasively used due to users have to install that plug-in firstly.&lt;/p>
&lt;p>I searched a similar &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282419">request&lt;/a> on bugzilla, then I initialized my contribution in the early of this year. Finally it was accepted and will release as part of eclipse itself since Eclipse 3.7 M7! I hope it would benefit the users of Eclipse more and more.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/eclipse-p2s-importexport-capability/">Read More&lt;/a>&lt;/p></description></item><item><title>[vim] delete the lines not contain words</title><link>https://kane.mx/posts/archive/blogspot/vim-delete-lines-not-contain-words/</link><pubDate>Wed, 05 Jan 2011 14:25:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/vim-delete-lines-not-contain-words/</guid><description>
&lt;p>:g!/some expression/d&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/vim-delete-lines-not-contain-words/">Read More&lt;/a>&lt;/p></description></item><item><title>Inside P2's profile (2) - the fragment matches all osgi bundles</title><link>https://kane.mx/posts/archive/blogspot/inside-p2s-profile-2-fragment-matches/</link><pubDate>Tue, 28 Dec 2010 11:33:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/inside-p2s-profile-2-fragment-matches/</guid><description>
&lt;p>Recently our installer met a strange bug, it didn't uninstall all legacy bundles after updating to new version. Finally I found it's due to a magic fragment is missing in the profile due to some causes.&lt;/p>
&lt;p>    &lt;unit id='tooling.osgi.bundle.default' version='1.0.0' singleton='false'>&lt;br>
      &lt;hostRequirements size='1'>&lt;br>
        &lt;required namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' range='0.0.0' multiple='true' greedy='false'/>&lt;br>
      &lt;/hostRequirements>&lt;br>
      &lt;properties size='1'>&lt;br>
        &lt;property name='org.eclipse.equinox.p2.type.fragment' value='true'/>&lt;br>
      &lt;/properties>&lt;br>
      &lt;provides size='2'>&lt;br>
        &lt;provided namespace='org.eclipse.equinox.p2.iu' name='tooling.osgi.bundle.default' version='1.0.0'/>&lt;br>
        &lt;provided namespace='org.eclipse.equinox.p2.flavor' name='tooling' version='1.0.0'/>&lt;br>
      &lt;/provides>&lt;br>
      &lt;requires size='1'>&lt;br>
        &lt;required namespace='org.eclipse.equinox.p2.eclipse.type' name='bundle' range='0.0.0' multiple='true' greedy='false'/>&lt;br>
      &lt;/requires>&lt;br>
      &lt;touchpoint id='null' version='0.0.0'/>&lt;br>
      &lt;touchpointData size='1'>&lt;br>
        &lt;instructions size='4'>&lt;br>
          &lt;instruction key='install'>&lt;br>
            installBundle(bundle:${artifact})&lt;br>
          &lt;/instruction>&lt;br>
          &lt;instruction key='uninstall'>&lt;br>
            uninstallBundle(bundle:${artifact})&lt;br>
          &lt;/instruction>&lt;br>
          &lt;instruction key='unconfigure'>&lt;/p>
&lt;p>          &lt;/instruction>&lt;br>
          &lt;instruction key='configure'>&lt;br>
            setStartLevel(startLevel:4);&lt;br>
          &lt;/instruction>&lt;br>
        &lt;/instructions>&lt;br>
      &lt;/touchpointData>&lt;br>
    &lt;/unit>&lt;/p>
&lt;p>It has 'hostRequirements' element that represents it's a fragment IU and match all the eclipse's plug-ins in that profile. And this fragment defines the touch point actions for its hosts that will do installBundle action during 'install' phrase and uninstallBundle action during 'uninstall' phrase. It's a very good way to remove the duplicate touch point definitions for all eclipse's plug-ins in the profile.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/inside-p2s-profile-2-fragment-matches/">Read More&lt;/a>&lt;/p></description></item><item><title>Inside P2's profile (1) - inclusion rules</title><link>https://kane.mx/posts/archive/blogspot/inside-p2s-profile-1-inclusion-rules/</link><pubDate>Tue, 28 Dec 2010 11:13:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/inside-p2s-profile-1-inclusion-rules/</guid><description>
&lt;p>You would see some interesting properties at the bottom of eclipse's profile.&lt;/p>
&lt;p>For example,&lt;/p>
&lt;iuProperties id='org.eclipse.sdk.ide' version='3.6.1.M20100909-0800'>
      &lt;properties size='2'>
        &lt;property name='org.eclipse.equinox.p2.internal.inclusion.rules' value='STRICT'/>
      &lt;/properties>
&lt;/iuProperties>
&lt;p>It attaches a property named 'org.eclipse.equinox.p2.internal.inclusion.rules' with value 'STRICT' on the IU 'org.eclipse.sdk.ide' with version 3.6.1.M20100909-0800.&lt;br>
 &lt;br>
It's a very important property for the p2 engine. It means the IU 'org.eclipse.sdk.ide' has been explicitly installed into the profile, so it's not allowed be implicitly updated or removed.&lt;/p>
&lt;p>For example,&lt;br>
We have top feature IU 'org.eclipse.sdk.ide' that represents the Eclipse SDK,   'org.eclipse.pde.feature' that represents the Plug-in Development Tool and 'org.eclipse.jdt.feature' that represents the Java Development Tool. And both JDT and PDT are part of Eclipse SDK, so 'org.eclipse.pde.feature' and 'org.eclipse.jdt.feature' are required by 'org.eclipse.sdk.ide'.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/inside-p2s-profile-1-inclusion-rules/">Read More&lt;/a>&lt;/p></description></item><item><title>stack overflow protector</title><link>https://kane.mx/posts/archive/blogspot/stack-overflow-protector/</link><pubDate>Thu, 23 Dec 2010 13:25:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/stack-overflow-protector/</guid><description>
&lt;p>Latest gcc compiler enables the stack overflow protector that is since GLIBC 2.4. So the library or executable is compiled by latest gcc could be loaded or executed in RHEL4 or Solaris 9 that only have GLIBC 2.3. Hence using option '-fno-stack-protector' to compile the library or executable to make sure it could be executed in older linux release.&lt;/p>
&lt;p>g++ -fno-stack-protector -o test.o test&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/stack-overflow-protector/">Read More&lt;/a>&lt;/p></description></item><item><title>the loop name for 'for' clause in java</title><link>https://kane.mx/posts/archive/blogspot/loop-name-for-for-clause-in-java/</link><pubDate>Tue, 21 Sep 2010 10:46:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/loop-name-for-for-clause-in-java/</guid><description>
&lt;p>Recently I just know such a useful syntax usage of java.&lt;/p>
&lt;pre>&lt;code>aLoopName: for (;;) {   // ...  while (someCondition)   // ...    if (otherCondition)       continue aLoopName;
&lt;/code>&lt;/pre>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/loop-name-for-for-clause-in-java/">Read More&lt;/a>&lt;/p></description></item><item><title>rename command</title><link>https://kane.mx/posts/archive/blogspot/rename-command/</link><pubDate>Sun, 19 Sep 2010 11:40:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/rename-command/</guid><description>
&lt;p>It's a powerful command to rename files in a batch.&lt;/p>
&lt;p>Usage:&lt;/p>
&lt;p>rename 's/(\d+)$/$1\.txt/' * rename add '.txt' extension name for all files that ends with number.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/rename-command/">Read More&lt;/a>&lt;/p></description></item><item><title>applying proxy for the softwares without proxy support in linux</title><link>https://kane.mx/posts/archive/blogspot/applying-proxy-for-softwares-without/</link><pubDate>Mon, 13 Sep 2010 13:14:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/applying-proxy-for-softwares-without/</guid><description>
&lt;p>If you have http proxy, set it to system environment,&lt;/p>
&lt;p>export http_proxy=http://&lt;a href="http://127.0.0.1">127.0.0.1&lt;/a>:8000 Then start the application in that same terminal.&lt;/p>
&lt;p>If the proxy is socks proxy, use '&lt;a href="http://tsocks.sourceforge.net/about.php">tsocks&lt;/a>' to wrap the application in terminal.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/applying-proxy-for-softwares-without/">Read More&lt;/a>&lt;/p></description></item><item><title>Food and Drinking</title><link>https://kane.mx/posts/archive/blogspot/food-and-drinking/</link><pubDate>Mon, 30 Aug 2010 15:11:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/food-and-drinking/</guid><description>
&lt;p>Honestly speaking, you have eaten the best delicious food if you're living in China. Though we have more and more concerns on the safety of food, we have to recognize that Chinese food is more delicious than others.&lt;/p>
&lt;p>The cuisine is simple in Austria. People always use pork, beef, flour, tomato, potato and few green vegetables. So they surprised Chinese cost several hours to make the food.&lt;/p>
&lt;p>&lt;a href="http://lh4.ggpht.com/_5seoFihTGKg/TGhDMuC9-GI/AAAAAAAAEts/07UdMerwnek/s1600/DSC01486.JPG">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="320"
height="180"
src="https://kane.mx/DSC01486_5497315126248538115.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/food-and-drinking/">Read More&lt;/a>&lt;/p></description></item><item><title>Working Workspace</title><link>https://kane.mx/posts/archive/blogspot/working-workspace/</link><pubDate>Fri, 27 Aug 2010 17:29:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/working-workspace/</guid><description>
&lt;p>Joel posted a &lt;a href="http://www.joelonsoftware.com/articles/fieldguidetodevelopers.html">blog&lt;/a> related to how to hire the great programmers. One of his key points is building comfortable workspaces.&lt;/p>
&lt;p>I believe every programmer loves the workspace like Google and Fog Creek. The workspace of Google has been very famous due to its French chef, gymnasium and big sofas. Why is Fog Creek? It's the company created by Joel, he also practiced his theory on his company. Ruan YiFeng posted a &lt;a href="http://www.ruanyifeng.com/blog/2009/02/fog_creek_s_new_office.html">blog&lt;/a> for it. I bet you would envy the guys working in that office.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/working-workspace/">Read More&lt;/a>&lt;/p></description></item><item><title>Transportation</title><link>https://kane.mx/posts/archive/blogspot/transportation/</link><pubDate>Fri, 27 Aug 2010 16:20:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/transportation/</guid><description>
&lt;p>Salzburg is a small city and is on the banks of the Salzach River. It's easy to go through the city by bus in 30 minutes.&lt;/p>
&lt;p>&lt;a href="http://lh5.ggpht.com/_5seoFihTGKg/TGhDE2zZzpI/AAAAAAAAEts/7yYsaAnjIvg/s1600/IMAG0058.jpg">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="320"
height="192"
src="https://kane.mx/IMAG0058_5033465335237907880.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>Salzach River&lt;/p>
&lt;p>&lt;a href="http://lh4.ggpht.com/_5seoFihTGKg/TF7wirfvyNI/AAAAAAAAEJo/Q92doV8uMyU/s1600/DSC01291.JPG">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="320"
height="180"
src="https://kane.mx/DSC01291_14853324469084525771.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>outline view&lt;/p>
&lt;p>Riding the bicycle is a very good way to enjoy the beautiful sight of the city. You could see many kids with parents riding bicycle in the sunny weekend.&lt;br>
The train station and a major bus transient station are the same one that is called as 'main station' by local residents. it's not far from the office of company, about 20 minutes by foot.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/transportation/">Read More&lt;/a>&lt;/p></description></item><item><title>Working style</title><link>https://kane.mx/posts/archive/blogspot/working-style/</link><pubDate>Fri, 20 Aug 2010 17:45:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/working-style/</guid><description>
&lt;p>There are 20+ staffs in Salzburg office. Most of them are developers, one is administrator of office.&lt;br>
Generally the staffs in Salzburg work more flexible than the staffs working in Beijing.&lt;br>
Some of them live in German. Even though it's not so far as Salzburg, they also need come to Salzburg by train. So sometimes they work at home, use internet and phone as communication tool.&lt;br>
And they have different responsibilities for products. For example, Helmut works on installer, Matthias and Michael are responsibility for QFT testing, Martin N. is focus on license API developing. So everybody has himself schedule, he can decide when he come to office and when leave office based on his working schedule. Nobody cares when you come/leave office or how long you work every day. I believe all of them do well on their jobs.&lt;br>
Furthermore you can work with your dogs together if nobody takes care of them at home.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/working-style/">Read More&lt;/a>&lt;/p></description></item><item><title>day 1</title><link>https://kane.mx/posts/archive/blogspot/day-1/</link><pubDate>Tue, 10 Aug 2010 19:24:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/day-1/</guid><description>
&lt;p>度过长途飞行的旅程不是一件容易的事。要在狭小的空间里待上近10个小时，好在是两人出行，半睡半聊的打发过了时间。&lt;br>
到达维也纳之后，出了登机通道看到的居然是一个酒吧类的餐馆。感觉很稀奇，也很有味道。&lt;br>
周围当然少不了免税店和商铺，但远没有首都机场那样的规模。总体感觉就像国内大型超市购物出口一样，而且人也不多。&lt;/p>
&lt;p>&lt;a href="http://lh3.ggpht.com/_5seoFihTGKg/TGHDEkhP_yI/AAAAAAAAENE/vaUaP6QSc5o/s1600/IMAG0012.jpg">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="192"
height="320"
src="https://kane.mx/IMAG0012_584699872206005858.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>另外赞一下维也纳机场的Wifi，简单配置就K了，哪像国内的，又要移动号码，还要短信获取，搞半天也没弄定。&lt;br>
转机之前还有段时间，就在机场里到处逛了逛。顺便在一个吧解决了晚餐，同时也尝了杯当地啤酒。&lt;/p>
&lt;p>&lt;a href="http://lh3.ggpht.com/_5seoFihTGKg/TGHDGKzhOgI/AAAAAAAAENI/SyDJegD6gsU/s1600/IMAG0013.jpg">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="192"
height="320"
src="https://kane.mx/IMAG0013_3323993232420467989.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>去萨尔茨堡的飞机还是带螺旋桨的，头次坐这样的老式飞机。&lt;/p>
&lt;p>&lt;a href="http://lh5.ggpht.com/_5seoFihTGKg/TF7tgvXQbhI/AAAAAAAAECI/AgjugZ-dPW0/s1600/DSC01197.JPG">&lt;figure>
&lt;picture>
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="320"
height="180"
src="https://kane.mx/DSC01197_12948264192493874901.jpg"
/>&lt;/picture>
&lt;/figure>
&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/day-1/">Read More&lt;/a>&lt;/p></description></item><item><title>Discovering the p2 API</title><link>https://kane.mx/posts/archive/blogspot/discovering-p2-api/</link><pubDate>Mon, 17 May 2010 22:35:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/discovering-p2-api/</guid><description>
&lt;p>Check out this SlideShare Presentation:&lt;/p>
&lt;p>&lt;strong>&lt;a href="http://www.slideshare.net/PascalRapicault/discovering-the-p2-api" title="Discovering the p2 API">Discovering the p2 API&lt;/a>&lt;/strong>&lt;/p>
&lt;p>View more &lt;a href="http://www.slideshare.net/">presentations&lt;/a> from &lt;a href="http://www.slideshare.net/PascalRapicault">Sonatype&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/discovering-p2-api/">Read More&lt;/a>&lt;/p></description></item><item><title>P2 replication tool lives on Eclipse Marketplace</title><link>https://kane.mx/posts/archive/blogspot/p2-replication-tool-lives-on-eclipse/</link><pubDate>Mon, 17 May 2010 15:41:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/p2-replication-tool-lives-on-eclipse/</guid><description>
&lt;p>Days ago I updated my p2 replication tool. It's easier to install it in your Eclipse.&lt;br>
A new component named 'Eclipse marketplace' is added into Eclipse SDK since Helios, which is an application store for Eclipse. People could be easy to install third party plug-ins into their Eclipse.&lt;/p>
&lt;p>You can launch marketplace via 'Help' - 'Eclipse Marketplace...', then search key word 'p2' or 'replication' to find the tool. Finally click next to install it.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/p2-replication-tool-lives-on-eclipse/">Read More&lt;/a>&lt;/p></description></item><item><title>useful network utility tools</title><link>https://kane.mx/posts/archive/blogspot/useful-network-utility-tools/</link><pubDate>Thu, 11 Mar 2010 14:53:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/useful-network-utility-tools/</guid><description>
&lt;p>1. tcpdump&lt;br>
tcpdump -n port 80 -i eth0|lo&lt;br>
monitor all package transferred on 80 port on the network interface eth0/lo&lt;br>
2. netstat&lt;br>
netstat -anp|grep java&lt;br>
trace all network traffic on the process named java&lt;br>
netstat -anp|grep 128.224.159.xxx&lt;br>
trace all network traffic on the host whose ip address is 128.224.159.xxx&lt;br>
3. nslookup&lt;br>
nslookup 206.191.52.46&lt;br>
look up the domain name whose ip address is 206.191.52.46&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/useful-network-utility-tools/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]Find -exec tip</title><link>https://kane.mx/posts/archive/blogspot/find-exec-tip/</link><pubDate>Wed, 24 Feb 2010 13:46:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/find-exec-tip/</guid><description>
&lt;p>Using -exec command like below, need add escape character for semicolon that separated two commands in shell&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">find directory/ -type d -exec chmod a+x &lt;span class="o">{}&lt;/span> &lt;span class="se">\\&lt;/span>&lt;span class="p">;&lt;/span> &lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;blockquote>
&lt;p>Feb 24, 2010 - update:&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">find . -maxdepth &lt;span class="m">4&lt;/span> -type d  -name &lt;span class="s1">&amp;#39;g-vxworks&amp;#39;&lt;/span> 2&amp;gt;/dev/null -print&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;blockquote>
&lt;p>Jan. 7, 2024 - update:
You might see &lt;code>No such file or directory&lt;/code> when combining &lt;code>--exec rm&lt;/code> to delete the found files.&lt;/p>&lt;/blockquote>
&lt;p>You can add &lt;code>-depth&lt;/code> option to mitigate the message.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/find-exec-tip/">Read More&lt;/a>&lt;/p></description></item><item><title>special characters in p2 touchpoint instruction</title><link>https://kane.mx/posts/archive/blogspot/special-characters-in-p2-touchpoint/</link><pubDate>Fri, 05 Feb 2010 16:15:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/special-characters-in-p2-touchpoint/</guid><description>
&lt;p>I suffered p2 installation failed on the configure parse. Becase I try to add vm arguments for my application.&lt;br>
For example, I added '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8272' in the product configuration.&lt;br>
P2 will fail when parsing the argument, because it contains ':' and ',' that should be escaped.&lt;br>
It works again after replacing it to '-agentlib${#58}jdwp=transport=dt_socket${#44}server=y${#44}suspend=n${#44}address=8272'.&lt;br>
The more detail note could be found in &lt;a href="http://wiki.eclipse.org/Equinox/p2/Engine/Touchpoint_Instructions#Variables_Available_in_all_phases">p2 touchpoint wiki&lt;/a>.&lt;br>
And I also opened &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=301927">bug&lt;/a> to request improving it.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/special-characters-in-p2-touchpoint/">Read More&lt;/a>&lt;/p></description></item><item><title>mount windows share folder</title><link>https://kane.mx/posts/archive/blogspot/mount-windows-share-folder/</link><pubDate>Fri, 29 Jan 2010 13:22:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/mount-windows-share-folder/</guid><description>
&lt;p>mount -t cifs -o username=xxx,password=xxx,workgroup=xx,iocharset=utf8 //share.domain/folder /localfolder&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/mount-windows-share-folder/">Read More&lt;/a>&lt;/p></description></item><item><title>the way to dump hex file</title><link>https://kane.mx/posts/archive/blogspot/way-to-dump-hex-file/</link><pubDate>Wed, 27 Jan 2010 17:27:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/way-to-dump-hex-file/</guid><description>
&lt;p>1. open the file in vim, :%!xxd&lt;br>
2. hexdump&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/way-to-dump-hex-file/">Read More&lt;/a>&lt;/p></description></item><item><title>How to get the name of running test case in JUnit4</title><link>https://kane.mx/posts/archive/blogspot/how-to-get-name-of-running-test-case-in/</link><pubDate>Mon, 11 Jan 2010 14:57:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-get-name-of-running-test-case-in/</guid><description>
&lt;pre>&lt;code>public class NameRuleTest {     @Rule public TestName name = new TestName();         @Test public void testA() {                 assertEquals(&amp;quot;testA&amp;quot;, name.getMethodName());         }        @Test public void testB() {                 assertEquals(&amp;quot;testB&amp;quot;, name.getMethodName());         }}
&lt;/code>&lt;/pre>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-get-name-of-running-test-case-in/">Read More&lt;/a>&lt;/p></description></item><item><title>How p2 UI handles with license agreements</title><link>https://kane.mx/posts/archive/blogspot/how-p2-ui-handles-with-license/</link><pubDate>Wed, 30 Dec 2009 16:56:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-p2-ui-handles-with-license/</guid><description>
&lt;p>P2 install wizard firstly query the repository to find out the root installable unit(as well as top installable). Then p2 recalculate the dependency and try to search the requirements in all available repositories after user submits their installation request. Go to the license agreement page if all the dependencies are satisfied.&lt;/p>
&lt;p>P2 agreement page obtains all the units to be installed from the operands of provision plan. The number always is much greater than the number submitted by user. Because the submitted IUs only are the root IUs.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-p2-ui-handles-with-license/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]ssh key</title><link>https://kane.mx/posts/archive/blogspot/ssh-key/</link><pubDate>Tue, 29 Dec 2009 11:33:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/ssh-key/</guid><description>
&lt;p>Setup SSH without password.&lt;br>
a) execute &amp;quot;ssh-keygen -t rsa&amp;quot; under your linux/unix login to get the RSA keys.&lt;br>
(press Enter for all)&lt;br>
You will get 2 files uner ~/.ssh/, id_rsa and id_rsa.pub&lt;br>
b) Put the public key id_rsa.pub to your remote host: ~/.ssh/authorized_keys If the remote host share the same nfs, just try &amp;quot; cat id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&amp;quot;&lt;br>
* Remember to modify hostname or ip info in ~/.ssh/authorized_keys to &amp;quot;&lt;em>&amp;quot;, so that you can login from any host without password in your NIS domain.&lt;br>
For example:&lt;br>
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA4Ri5J0s1BL/+mR7RfAuDW6FY2P6ILc61Zvw1BdDkvHMFrTzaC/AUMw33H7biAMCXuCleakCuSoV8ZDiGHYs4wOVvet5sDmphkwdiC4xTekdl3dRNvGjMVbvFUta/Y5CiayL6YIu47Ro6Vvu4Mutsrv/13pTlifrEz+NTR/+bzMb9nTniCwiryMyYod3E46b8WvS8yE3WK+tH4BZE8bjiCwdvAzSdPyk/OFNrlBNuF1yewwnxv1roRD3UalT2+7O4kfEG9sMvvBHjuX2l7xlUe3stBftYpigBbwGmmadxjRpNIlk88t5xKcQX6nSu7V8HI3GWPHI0D+ISIlbfU5Sunw== kzhu0@&lt;/em>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/ssh-key/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse][P2]P2 replication plug-in</title><link>https://kane.mx/posts/archive/blogspot/p2-replication-plug-in/</link><pubDate>Fri, 25 Dec 2009 16:43:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/p2-replication-plug-in/</guid><description>
&lt;p>I wrote a plug-in to simplify the process to install the same plug-ins in different platform or different workstation.&lt;br>
Anyone is interested in it, pls follow below guide to freely use it.&lt;br>
&lt;a href="http://code.google.com/p/kane-toolkit/wiki/P2Replication">http://code.google.com/p/kane-toolkit/wiki/P2Replication&lt;/a>&lt;/p>
&lt;p>Enjoy it.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/p2-replication-plug-in/">Read More&lt;/a>&lt;/p></description></item><item><title>[eclipse]How Equinox load bundles</title><link>https://kane.mx/posts/archive/blogspot/how-equinox-load-bundles/</link><pubDate>Wed, 02 Dec 2009 14:58:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-equinox-load-bundles/</guid><description>
&lt;h1 id="how-equinox-load-bundles">How Equinox load bundles&lt;/h1>
&lt;p>Equinox launcher is responsible to start OSGi framework. The system bundle would be created and marked as installed when initializing the framework. Equinox also tries to install the installed bundles if finding them in persistence data during the initializing period. Of course there is no extra bundles would be installed when launching Equinox first time.&lt;/p>
&lt;p>Then Equinox launcher would install the bundles specified by vm's system property 'osgi.bundles'. And start the initial bundles that are marked as early start. For example, let's have a look at the configuration/config.ini of Eclipse, you would find a line similar as below,&lt;br>
osgi.bundles=reference\:file\:org.eclipse.equinox.simpleconfigurator_1.0.200.v20090831.jar@1\:start&lt;br>
It means the start level of bundle 'org.eclipse.equinox.simpleconfigurator_1.0.200.v20090831.jar' is 1, and it would be started after installing it.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-equinox-load-bundles/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse][P2]Learn p2 step by step</title><link>https://kane.mx/posts/archive/blogspot/learn-p2-step-by-step/</link><pubDate>Thu, 12 Nov 2009 17:48:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/learn-p2-step-by-step/</guid><description>
&lt;h1 id="learn-p2-step-by-step">Learn p2 step by step&lt;/h1>
&lt;blockquote>
&lt;p>See &lt;a href="https://docs.google.com/document/d/1mDhET8al4FO4zlafeTUcXqFEopGbKqWZ5UQ2EbMH20Y/edit?usp=sharing">this link&lt;/a> for detail&lt;/p>&lt;/blockquote>
&lt;ol>
&lt;li>
&lt;p>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#Learn_P2_step_by_step">Learn P2 step by step&lt;/a>&lt;/p>
&lt;ol>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#p2_concept">p2 concept&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#p2_install">p2 install&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#p2_install_practice">p2 install practice&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#p2_repository_publish">p2 repository publish&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#customized_p2_touchpoint">customized p2 touchpoint&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#p2_repository_publish_practice">p2 repository publish practice&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#Example_Code">Example Code&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.blogger.com/post-edit.g?blogID=8314384370778429245&amp;amp;postID=6549693887265291061#Reference">Reference&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ol>
&lt;h3 id="p2-concept">p2 concept&lt;/h3>
&lt;p>首先来理解p2引入的几个概念[1]&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>p2 / Agent&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The provisioning infrastructure on client machines&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Installable Unit (IU)&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Metadata&lt;/strong> that describes things that can be installed/configured&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Artifact&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The actual content being installed/configured(e.g., bundle JARs)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Repository&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>A store of metadata or artifacts&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/learn-p2-step-by-step/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]ssh forward</title><link>https://kane.mx/posts/archive/blogspot/ssh-forward/</link><pubDate>Wed, 28 Oct 2009 15:29:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/ssh-forward/</guid><description>
&lt;p>ssh -qTfnN -D LocalPort remotehost&lt;/p>
&lt;p>All the added options are for a ssh session that's used for tunneling.&lt;/p>
&lt;p>-q :- be very quite, we are acting only as a tunnel.&lt;br>
-T :- Do not allocate a pseudo tty, we are only acting a tunnel.&lt;br>
-f :- move the ssh process to background, as we don't want to interact with this ssh session directly.&lt;br>
-N :- Do not execute remote command.&lt;br>
-n :- redirect standard input to /dev/null.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/ssh-forward/">Read More&lt;/a>&lt;/p></description></item><item><title>Simulate p2 self host in Eclipse run</title><link>https://kane.mx/posts/archive/blogspot/simulate-p2-self-host-in-eclipse-run/</link><pubDate>Tue, 27 Oct 2009 16:12:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/simulate-p2-self-host-in-eclipse-run/</guid><description>
&lt;p>-Dosgi.install.area=&amp;lt;launcher's folder&amp;gt;&lt;br>
-Declipse.p2.profile=&lt;profile id>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/simulate-p2-self-host-in-eclipse-run/">Read More&lt;/a>&lt;/p></description></item><item><title>Eclipse/OSGi preference</title><link>https://kane.mx/posts/archive/blogspot/eclipseosgi-preference/</link><pubDate>Thu, 22 Oct 2009 15:29:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/eclipseosgi-preference/</guid><description>
&lt;p>The IPreferenceStore API of Eclipse is based on OSGi's preferences service. Equinox implements several scope context for different preferences, such DefaultScope, InstanceScope and ConfigurationScope. The IPreferenceStore is the wrapper of instance scope for back-compatibility. It stored the data in workspace(osgi.data.area).&lt;/p>
&lt;p>The workspace folder would be created when launching RCP application if it doesn't exist. But we can use argument '-data @none' to suppress the creation of workspace. If that, the instance scope/IPreferenceStore can't store any value any more.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/eclipseosgi-preference/">Read More&lt;/a>&lt;/p></description></item><item><title>The usage of Eclipse's Proxy API</title><link>https://kane.mx/posts/archive/blogspot/usage-of-eclipses-proxy-api/</link><pubDate>Wed, 21 Oct 2009 16:53:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/usage-of-eclipses-proxy-api/</guid><description>
&lt;p>Eclipse platform register an OSGi service 'IProxyService' to manage network connection, which has capability to set proxy setting. There are three types of proxy working mode,&lt;/p>
&lt;ul>
&lt;li>Direct(no proxy),&lt;/li>
&lt;li>Manual(specified by user),&lt;/li>
&lt;li>Native(using OS's proxy setting, such as gnome-proxy, IE).&lt;/li>
&lt;/ul>
&lt;p>There are three types of proxy supported by IProxyService. They're http, https and socks.&lt;/p>
&lt;p>It also allows to add/remove ip address from white list, which are accessed without connecting proxy.&lt;/p>
&lt;p>End users can manage the proxy setting of Eclipse via Preference - General - Network Connections. Eclipse would do persistence of user's setting. Other components of Eclipse also use those proxy settings to access network, such as ECF.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/usage-of-eclipses-proxy-api/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]Turn off automatically scanning disk when reboot</title><link>https://kane.mx/posts/archive/blogspot/turnoff-automatically-scanning-disk/</link><pubDate>Wed, 11 Feb 2009 17:40:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/turnoff-automatically-scanning-disk/</guid><description>
&lt;p>tune2fs -i 0 -c 0 /dev/sdx&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/turnoff-automatically-scanning-disk/">Read More&lt;/a>&lt;/p></description></item><item><title>How to set default input method for GNOME</title><link>https://kane.mx/posts/archive/blogspot/how-to-set-default-input-method-for/</link><pubDate>Mon, 09 Feb 2009 11:24:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-set-default-input-method-for/</guid><description>
&lt;p>add below lines in ~/.gnomerc&lt;/p>
&lt;p>export XMODIFIERS=&amp;quot;@im=fcitx&amp;quot;&lt;br>
export GTK_IM_MODULE=&amp;quot;xim&amp;quot;&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-set-default-input-method-for/">Read More&lt;/a>&lt;/p></description></item><item><title>[HowTo]How to set up jre environment in firefox</title><link>https://kane.mx/posts/archive/blogspot/how-to-set-up-jre-environment-in/</link><pubDate>Mon, 29 Dec 2008 12:52:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-set-up-jre-environment-in/</guid><description>
&lt;p>create symbol link under lib/plugins of firefox to link jre/plugins/i386/ns**/libjavaplugin_oji.so&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-set-up-jre-environment-in/">Read More&lt;/a>&lt;/p></description></item><item><title>[Debug][tip]How to ignore specified signal when debugging program via gdb</title><link>https://kane.mx/posts/archive/blogspot/how-to-ignore-specified-signal-when/</link><pubDate>Wed, 10 Dec 2008 15:02:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-ignore-specified-signal-when/</guid><description>
&lt;p>Such as,&lt;br>
(gdb) handle SIGPIPE nostop noprint pass&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-ignore-specified-signal-when/">Read More&lt;/a>&lt;/p></description></item><item><title>[HowTo][tip]How to adjust the font size of Notes editor</title><link>https://kane.mx/posts/archive/blogspot/how-to-adjust-font-size-of-notes-editor/</link><pubDate>Thu, 04 Dec 2008 13:11:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-adjust-font-size-of-notes-editor/</guid><description>
&lt;p>Close Notes&lt;br>
Double click c:\notes\notes.ini to open it.&lt;br>
Add one new line &amp;quot;Display_font_adjustment=n&amp;quot; after the third line in notes.ini file. &amp;quot;n&amp;quot; is the number.It can be 1or 2 or 3....and the font will be larger with the number increasing.&lt;br>
Launch note&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-adjust-font-size-of-notes-editor/">Read More&lt;/a>&lt;/p></description></item><item><title>[OSGi][Eclipse]Add custom jar or path into Equinox Framework</title><link>https://kane.mx/posts/archive/blogspot/add-custom-jar-or-path-into-equinox/</link><pubDate>Sun, 28 Sep 2008 13:23:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/add-custom-jar-or-path-into-equinox/</guid><description>
&lt;p>Set vm arguments 'osgi.framework.extensions' and 'osgi.frameworkClassPath' when vm starts. If those value are set, those jar or path would be added into the classloader when starting EclipseStarter.&lt;/p>
&lt;p>See org.eclipse.equinox.launcher.Main for more details in the source code of Eclipse 3.4.&lt;br>
Best Regards&lt;br>
Kane&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/add-custom-jar-or-path-into-equinox/">Read More&lt;/a>&lt;/p></description></item><item><title>[OSGi]How to acquire the fragments of specified bundle</title><link>https://kane.mx/posts/archive/blogspot/osgihow-to-acquire-fragments-of/</link><pubDate>Fri, 01 Aug 2008 16:22:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/osgihow-to-acquire-fragments-of/</guid><description>
&lt;p>The answer is very simple, using the service 'org.eclipse.service.PackageAdmin'.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/osgihow-to-acquire-fragments-of/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse]Equinox's classloader and its URL schema</title><link>https://kane.mx/posts/archive/blogspot/eclipseequinoxs-classloader-and-its-url/</link><pubDate>Thu, 17 Jul 2008 17:42:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/eclipseequinoxs-classloader-and-its-url/</guid><description>
&lt;p>Equinox uses the adaptor hooks to implement the class loader.&lt;br>
See &lt;a href="http://wiki.eclipse.org/Adaptor_Hooks">http://wiki.eclipse.org/Adaptor_Hooks&lt;/a> for more detail&lt;/p>
&lt;p>BaseClassLoadingHook would search the native code on itself. If it find the file in that jar file, it would extract the native library into its storage folder.&lt;/p>
&lt;p>EclipseClassLoadingHook defines some variables to search the native library. Belows are built-in variables:&lt;/p>
&lt;p>result.add(&amp;quot;ws/&amp;quot; + info.getWS() + &amp;quot;/&amp;quot;); //$NON-NLS-1$ //$NON-NLS-2$&lt;br>
result.add(&amp;quot;os/&amp;quot; + info.getOS() + &amp;quot;/&amp;quot; + info.getOSArch() + &amp;quot;/&amp;quot;); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$&lt;br>
result.add(&amp;quot;os/&amp;quot; + info.getOS() + &amp;quot;/&amp;quot;); //$NON-NLS-1$ //$NON-NLS-2$&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/eclipseequinoxs-classloader-and-its-url/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip][vim]排版小技巧</title><link>https://kane.mx/posts/archive/blogspot/tipvim/</link><pubDate>Tue, 15 Jul 2008 11:00:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/tipvim/</guid><description>
&lt;p>    1. 将要排版的文字贴到vim了&lt;br>
    2.  set textwidth=70&lt;br>
    3. visual模式下选择要排版的文字,按gq, 就变成70字母1行的格式了&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/tipvim/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]convert dos format to unix</title><link>https://kane.mx/posts/archive/blogspot/tipconvert-dos-format-to-unix/</link><pubDate>Fri, 23 May 2008 18:03:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/tipconvert-dos-format-to-unix/</guid><description>
&lt;p>In vi/vim,&lt;/p>
&lt;p>﻿set file format=unix&lt;/p>
&lt;p>or dos2unix, unix2dos&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/tipconvert-dos-format-to-unix/">Read More&lt;/a>&lt;/p></description></item><item><title>[tip]Makefile</title><link>https://kane.mx/posts/archive/blogspot/makefile-tip/</link><pubDate>Thu, 22 May 2008 20:37:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/makefile-tip/</guid><description>
&lt;p>Build c/c++ project always need third party library on linux, such as gtk+, glib. Writing their absolute path in Makefile is not flexible way. You can use pkg-config instead of the absolute path. Below is code snippet:&lt;/p>
&lt;p>GTK_LIB=$(shell pkg-config --libs gtk+-2.0)&lt;br>
GTK_INC=$(shell pkg-config --cflags gtk+-2.0)&lt;/p>
&lt;p>gcc -o yourlibrary.so $(GTK_INC) $(GTK_LIB)&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/makefile-tip/">Read More&lt;/a>&lt;/p></description></item><item><title>[OSGi][Equinox]URL Handlers Service</title><link>https://kane.mx/posts/archive/blogspot/url-handlers-service/</link><pubDate>Wed, 16 Apr 2008 14:20:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/url-handlers-service/</guid><description>
&lt;p>OSGi provides a mechanism to let user contribute custom schemes automatically. It avoid some restriction with Java facilities for extending the handlers. The more detail could be found from OSGi specification R4, which has description how OSGi implements URL Handler Service.&lt;/p>
&lt;p>Use a sample to illustrate how to contribute your scheme(protocol):&lt;/p>
&lt;p>1. register your URLStreamHandlerService implementation, which must contain a property named &amp;quot;url.handler.protocol&amp;quot;. below register my scheme 'smb'&lt;br>
public void start(BundleContext context) throws Exception {&lt;br>
Hashtable properties = new Hashtable();&lt;br>
properties.put( URLConstants.URL_HANDLER_PROTOCOL, new String[] { &amp;quot;smb&amp;quot; } );&lt;br>
context.registerService(URLStreamHandlerService.class.getName(), new SmbURLHandler(), properties );&lt;br>
}&lt;br>
2. your URL Handler extends AbstractURLStreamHandlerService, and implements abstract function 'openConnection(URL)'&lt;br>
public class SmbURLHandler extends AbstractURLStreamHandlerService {&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/url-handlers-service/">Read More&lt;/a>&lt;/p></description></item><item><title>[OSGi][Equinox]the Bundle-NativeCode implementation in Equinox</title><link>https://kane.mx/posts/archive/blogspot/bundle-nativecode-implementation-in/</link><pubDate>Mon, 31 Mar 2008 17:36:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/bundle-nativecode-implementation-in/</guid><description>
&lt;p>OSGi Spec defines Bundle-NativeCode header to contain a specification of native code libraries contained in that bundle. All magic things are initialized by org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLibrary(String) and org.eclipse.osgi.framework.internal.core.BundleLoader.findLibrary(String). Then BundleLoader uses the org.eclipse.osgi.baseadaptor.BaseData(an implementation of BundleData) to find the library path, if the bundle is NOT a jar file, it would directly get the absolute path of library. Otherwise, the BaseData would extract the library file if it could NOT find it in OSGi bundle storage(located in ${data}/org.eclipse.osgi/bundles/[bundle_id]/.cp/). Refer to org.eclipse.osgi.baseadaptor.BaseData.findLibrary(String) for more detail.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/bundle-nativecode-implementation-in/">Read More&lt;/a>&lt;/p></description></item><item><title>[shell]Learning Note - 3/19/08</title><link>https://kane.mx/posts/archive/blogspot/linux-shelllearning-note-31908/</link><pubDate>Wed, 19 Mar 2008 14:35:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/linux-shelllearning-note-31908/</guid><description>
&lt;p>1&amp;gt; 是输出正确数据， 2&amp;gt; 则是错误数据输出项目, 若要同时写入同一个档案需要使用 2&amp;gt;&amp;amp;1 /dev/null 是什么呢？基本上，那就有点像是一个『黑洞』的垃圾桶功能！当你输入的任何东西导向到这个虚拟的垃圾桶装置时，『他就会凭空消失不见了～～』&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/linux-shelllearning-note-31908/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse]How to use qualifier string when exporting features and plug-ins</title><link>https://kane.mx/posts/archive/blogspot/how-to-use-qualifier-string-when/</link><pubDate>Tue, 11 Mar 2008 13:30:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/how-to-use-qualifier-string-when/</guid><description>
&lt;p>You must see the qualifier string property when exporting your features and plug-ins by Eclipse pde. But specified qualifier string won't appear after you export the features successfully.&lt;/p>
&lt;p>If you want to use the qualifier string, you must define your feature and plug-in version like below:&lt;br>
1.0.0.qualifier, 2.2.2.qaulifier&lt;/p>
&lt;p>:)&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/how-to-use-qualifier-string-when/">Read More&lt;/a>&lt;/p></description></item><item><title>万恶的注册表</title><link>https://kane.mx/posts/archive/blogspot/suck-windows-registry/</link><pubDate>Tue, 03 Apr 2007 13:16:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/suck-windows-registry/</guid><description>
&lt;p>最近几天被一个注册表相关的defect搞的焦头烂额。&lt;/p>
&lt;p>背景是这样的，产品在安装的时候需要通过修改注册表注册文件关联等信息。在先前安装程序基于InstallShield时工作正确，但在最近安装程序改用MSI后，我们写入注册表的信息没有被写到所期望的位置。&lt;/p>
&lt;p>通过各种试验，查找资料，终于搞明白原因。我们修改注册表的进程不是当前用户进程，而是系统进程，因此写入到HKEY_CURRENT_USER下的数据不能被写入到当前登陆用户下。&lt;/p>
&lt;p>We should not use &amp;quot;&lt;strong>HKEY_CURRENT_USER&amp;quot;&lt;/strong> to retrival current user's registry key value. Because Windows Services always startup before user login. It may happen some error or loading the wrong setting profile. If you still insist on using the current user registry key setting, please refer &amp;quot;&lt;em>&lt;a href="http://msdn.microsoft.com/library/default.asp?url=https://kane.mx/library/en-us/sysinfo/base/regopencurrentuser.asp">RegOpenCurrentUser&lt;/a>&lt;/em>&amp;quot;.&lt;/p>
&lt;p>最后只好将这些数据写到了Local Machine键值下。&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/suck-windows-registry/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse]get rid of the menus of eclipse platform</title><link>https://kane.mx/posts/archive/blogspot/get-rid-of-menus-of-eclipse-platform/</link><pubDate>Fri, 09 Mar 2007 13:46:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/get-rid-of-menus-of-eclipse-platform/</guid><description>
&lt;p>When you develop a rich client application base on eclipse framework, and your application require eclipse platform feature, you would find that your application has some menu items contributed by eclipse platform. Those menu items are defined by several plug-ins' implementation of actionSet extention point. In fact Eclipse provides an activity mechanism to suppress the extension points which you don't want to use. However, you must know the identification name of extension points which you want to suppress. It's a hard work to find out all of them from dozens of plugins. so, I wrote a utility function to list all the extension points of specified name.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/get-rid-of-menus-of-eclipse-platform/">Read More&lt;/a>&lt;/p></description></item><item><title>加载jar文件里的本地库</title><link>https://kane.mx/posts/archive/blogspot/jar/</link><pubDate>Wed, 24 Jan 2007 14:19:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/jar/</guid><description>
&lt;p>java程序开发中经常用到JNI调用本地library, 同时又希望将library同class文件编译成一个jar文件以方便deploy.&lt;/p>
&lt;p>但是JDK的classloader不支持从jar文件中加载library, 一个变通的方法就是jar里的library以临时文件的方式写到临时目录或java.library目录.&lt;/p>
&lt;p>附上两篇文档链接 :&lt;/p>
&lt;p>&lt;a href="http://www.javaworld.com.tw/jute/post/view?bid=29&amp;amp;id=173624&amp;amp;tpg=1&amp;amp;ppg=1&amp;amp;sty=1&amp;amp;age=0#173624">&lt;/a>**&lt;a href="http://www.javaworld.com.tw/jute/post/view?bid=29&amp;amp;id=173624&amp;amp;tpg=1&amp;amp;ppg=1&amp;amp;sty=1&amp;amp;age=0#173624">Load Library inside a jar file&lt;/a>&lt;br>
**&lt;/p>
&lt;p>&lt;a href="http://www.javaeye.com/topic/17713" title="固定链接：使用JNI时，装载本地库的小技巧">使用JNI时，装载本地库的小技巧&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/jar/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse]Eclipse update support</title><link>https://kane.mx/posts/archive/blogspot/eclipse-update-support/</link><pubDate>Wed, 17 Jan 2007 13:51:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/eclipse-update-support/</guid><description>
&lt;p>Those days my work is focus on eclipse's update. Now I understand the general mechanism and meet some issues when using it in development work.&lt;/p>
&lt;p>The update mechanism includes four major types: install, enable, disable and uninstall. And all of those operations can be executed by command line, such as installing a feature can use following line:&lt;br>
-application org.eclipse.update.core.standaloneUpdate -command install -featureId my.feature -version 1.0.0 -from file:/v:/local_updateSite/ -to file:/v:/eclipse/.&lt;br>
The installation process would copy the feature and plugins which are included by the feature to the local site from the update site, then execute the feature's global install handler if it has one.&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/eclipse-update-support/">Read More&lt;/a>&lt;/p></description></item><item><title>[Eclipse]The call sequence between partActivated and menu update</title><link>https://kane.mx/posts/archive/blogspot/call-sequence-between-partactivated-and/</link><pubDate>Thu, 19 Oct 2006 12:42:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/call-sequence-between-partactivated-and/</guid><description>
&lt;p>I met a defect that dynamically created menu items disappear after creating a new viewPart. It caused me overtime last Friday. Today I find the root cause.&lt;/p>
&lt;p>The scenario is:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>open first document, the items are shown well&lt;/p>
&lt;/li>
&lt;li>
&lt;p>open another document, the items disappear&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>The requirement is that showing the menu items while current part is document, otherwise hide them.&lt;/p>
&lt;p>So our implementation is:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>when current document part is deactivated, set menu items invisible&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/call-sequence-between-partactivated-and/">Read More&lt;/a>&lt;/p></description></item><item><title>[debug][java]Remote debug in Eclipse</title><link>https://kane.mx/posts/archive/blogspot/remote-debug-in-eclipse/</link><pubDate>Wed, 18 Oct 2006 12:53:00 +0800</pubDate><guid>https://kane.mx/posts/archive/blogspot/remote-debug-in-eclipse/</guid><description>
&lt;p>I need use remote debug in our project, however just some experience in Weblogic were found from internet. After my investigation, I got some experience about using Eclipse remote debug RCP.&lt;br>
There are two important parameters for jvm. And we must launch remote java app with those two parameters.&lt;br>
-Xdebug //tells jvm starting with debug mode&lt;br>
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044 //transport=dt_socket represents communication with socket, address=1044 represents that the port number is 1044&lt;br>
Then there are 3 steps in local env:&lt;br>
1.import source code into eclipse's project&lt;br>
2.Debug-Remote Java Application, see attachement as a sample&lt;br>
3.insert breakpoint,&lt;/p>
&lt;p>&lt;a href="https://kane.mx/posts/archive/blogspot/remote-debug-in-eclipse/">Read More&lt;/a>&lt;/p></description></item></channel></rss>